Diff

Differences From Artifact [3e9adabf49]:

To Artifact [fe7e6328bd]:


   139    139   	unsigned long long inode;
   140    140   	union {
   141    141   		struct {
   142    142   			int childcount;
   143    143   		} dir;
   144    144   		struct {
   145    145   			int executable;
   146         -			int suid;
          146  +			int suidRoot;
   147    147   			int worldaccessible;
   148    148   			off_t size;
   149    149   		} file;
   150    150   		struct {
   151    151   			off_t size;
   152    152   			char source[256];
   153    153   		} symlink;
................................................................................
   932    932   				}
   933    933   
   934    934   				break;
   935    935   			case 'f': /* file */
   936    936   				pathinfo->type = APPFS_PATHTYPE_FILE;
   937    937   				pathinfo->typeinfo.file.size = 0;
   938    938   				pathinfo->typeinfo.file.executable = 0;
   939         -				pathinfo->typeinfo.file.suid = 0;
          939  +				pathinfo->typeinfo.file.suidRoot = 0;
   940    940   				pathinfo->typeinfo.file.worldaccessible = 0;
   941    941   
   942    942   				Tcl_DictObjGet(interp, attrs_dict, attr_key_size, &attr_value);
   943    943   				if (attr_value != NULL) {
   944    944   					tcl_ret = Tcl_GetWideIntFromObj(NULL, attr_value, &attr_value_wide);
   945    945   					if (tcl_ret == TCL_OK) {
   946    946   						pathinfo->typeinfo.file.size = attr_value_wide;
................................................................................
   953    953   					for (attr_value_str_i = &attr_value_str[0]; *attr_value_str_i != '\0'; attr_value_str_i++) {
   954    954   						switch (*attr_value_str_i) {
   955    955   							case 'x':
   956    956   								pathinfo->typeinfo.file.executable = 1;
   957    957   
   958    958   								break;
   959    959   							case 'U':
   960         -								pathinfo->typeinfo.file.suid = 1;
          960  +								pathinfo->typeinfo.file.suidRoot = 1;
   961    961   
   962    962   								break;
   963    963   							case '-':
   964    964   								pathinfo->typeinfo.file.worldaccessible = 1;
   965    965   
   966    966   								break;
   967    967   						}
................................................................................
  1148   1148   	memcpy(buf, pathinfo.typeinfo.symlink.source, strlen(pathinfo.typeinfo.symlink.source) + 1);
  1149   1149   
  1150   1150   	return(0);
  1151   1151   }
  1152   1152   
  1153   1153   static int appfs_fuse_getattr(const char *path, struct stat *stbuf) {
  1154   1154   	struct appfs_pathinfo pathinfo;
         1155  +	int changeOwnerToUserIfPackaged;
  1155   1156   	int retval;
  1156   1157   
  1157   1158   	retval = 0;
  1158   1159   
  1159   1160   	APPFS_DEBUG("Enter (path = %s, ...)", path);
  1160   1161   
  1161   1162   #if (defined(DEBUG) && defined(APPFS_EXIT_PATH)) || defined(APPFS_EXIT_PATH_ENABLE_MAJOR_SECURITY_HOLE)
................................................................................
  1186   1187   
  1187   1188   	stbuf->st_mtime = pathinfo.time;
  1188   1189   	stbuf->st_ctime = pathinfo.time;
  1189   1190   	stbuf->st_atime = pathinfo.time;
  1190   1191   	stbuf->st_ino   = pathinfo.inode;
  1191   1192   	stbuf->st_mode  = 0;
  1192   1193   
         1194  +	changeOwnerToUserIfPackaged = 1;
         1195  +
  1193   1196   	switch (pathinfo.type) {
  1194   1197   		case APPFS_PATHTYPE_DIRECTORY:
  1195   1198   			stbuf->st_mode = S_IFDIR | 0555;
  1196   1199   			stbuf->st_nlink = 2 + pathinfo.typeinfo.dir.childcount;
  1197   1200   			break;
  1198   1201   		case APPFS_PATHTYPE_FILE:
         1202  +			stbuf->st_mode = S_IFREG | 0444;
         1203  +
  1199   1204   			if (pathinfo.typeinfo.file.executable) {
  1200         -				stbuf->st_mode = S_IFREG | 0555;
  1201         -			} else {
  1202         -				stbuf->st_mode = S_IFREG | 0444;
         1205  +				stbuf->st_mode |= 0111;
  1203   1206   			}
  1204   1207   
  1205         -			if (pathinfo.typeinfo.file.suid) {
  1206         -				stbuf->st_mode = S_IFREG | 04000;
         1208  +			if (pathinfo.typeinfo.file.suidRoot) {
         1209  +				changeOwnerToUserIfPackaged = 0;
         1210  +
         1211  +				stbuf->st_mode |= 04000;
  1207   1212   			}
  1208   1213   
  1209   1214   			if (pathinfo.typeinfo.file.worldaccessible) {
  1210   1215   				stbuf->st_mode &= ~077;
  1211   1216   			}
  1212   1217   
  1213   1218   			stbuf->st_nlink = 1;
................................................................................
  1235   1240   			break;
  1236   1241   		case APPFS_PATHTYPE_INVALID:
  1237   1242   			retval = -EIO;
  1238   1243   
  1239   1244   			break;
  1240   1245   	}
  1241   1246   
  1242         -	if (pathinfo.packaged) {
         1247  +	if (pathinfo.packaged && changeOwnerToUserIfPackaged) {
  1243   1248   		stbuf->st_uid   = appfs_get_fsuid();
  1244   1249   		stbuf->st_gid   = appfs_get_fsgid();
  1245   1250   		stbuf->st_mode |= 0200;
  1246   1251   	}
  1247   1252   
  1248   1253   	return(retval);
  1249   1254   }
................................................................................
  2006   2011   	 ** Add FUSE arguments which we always supply
  2007   2012   	 **/
  2008   2013   	fuse_opt_add_arg(args, "-odefault_permissions,fsname=appfs,subtype=appfsd,use_ino,kernel_cache,entry_timeout=0,attr_timeout=0,big_writes,intr,hard_remove");
  2009   2014   
  2010   2015   	if (getuid() == 0) {
  2011   2016   		fuse_opt_parse(args, NULL, NULL, NULL);
  2012   2017   		fuse_opt_add_arg(args, "-oallow_other");
         2018  +
         2019  +		/*
         2020  +		 * This should generally be avoided, but if there are security
         2021  +		 * concerns suid can be disabled completely on the commandline
         2022  +		 */
         2023  +		fuse_opt_parse(args, NULL, NULL, NULL);
         2024  +		fuse_opt_add_arg(args, "-osuid");
  2013   2025   	}
  2014   2026   
  2015   2027   	while ((ch = getopt(argc, argv, "dfshvo:")) != -1) {
  2016   2028   		switch (ch) {
  2017   2029   			case 'v':
  2018   2030   				/* Ignored */
  2019   2031   				break;