@@ -141,11 +141,11 @@ struct { int childcount; } dir; struct { int executable; - int suid; + int suidRoot; int worldaccessible; off_t size; } file; struct { off_t size; @@ -934,11 +934,11 @@ break; case 'f': /* file */ pathinfo->type = APPFS_PATHTYPE_FILE; pathinfo->typeinfo.file.size = 0; pathinfo->typeinfo.file.executable = 0; - pathinfo->typeinfo.file.suid = 0; + pathinfo->typeinfo.file.suidRoot = 0; pathinfo->typeinfo.file.worldaccessible = 0; Tcl_DictObjGet(interp, attrs_dict, attr_key_size, &attr_value); if (attr_value != NULL) { tcl_ret = Tcl_GetWideIntFromObj(NULL, attr_value, &attr_value_wide); @@ -955,11 +955,11 @@ case 'x': pathinfo->typeinfo.file.executable = 1; break; case 'U': - pathinfo->typeinfo.file.suid = 1; + pathinfo->typeinfo.file.suidRoot = 1; break; case '-': pathinfo->typeinfo.file.worldaccessible = 1; @@ -1150,10 +1150,11 @@ return(0); } static int appfs_fuse_getattr(const char *path, struct stat *stbuf) { struct appfs_pathinfo pathinfo; + int changeOwnerToUserIfPackaged; int retval; retval = 0; APPFS_DEBUG("Enter (path = %s, ...)", path); @@ -1188,24 +1189,28 @@ stbuf->st_ctime = pathinfo.time; stbuf->st_atime = pathinfo.time; stbuf->st_ino = pathinfo.inode; stbuf->st_mode = 0; + changeOwnerToUserIfPackaged = 1; + switch (pathinfo.type) { case APPFS_PATHTYPE_DIRECTORY: stbuf->st_mode = S_IFDIR | 0555; stbuf->st_nlink = 2 + pathinfo.typeinfo.dir.childcount; break; case APPFS_PATHTYPE_FILE: + stbuf->st_mode = S_IFREG | 0444; + if (pathinfo.typeinfo.file.executable) { - stbuf->st_mode = S_IFREG | 0555; - } else { - stbuf->st_mode = S_IFREG | 0444; + stbuf->st_mode |= 0111; } - if (pathinfo.typeinfo.file.suid) { - stbuf->st_mode = S_IFREG | 04000; + if (pathinfo.typeinfo.file.suidRoot) { + changeOwnerToUserIfPackaged = 0; + + stbuf->st_mode |= 04000; } if (pathinfo.typeinfo.file.worldaccessible) { stbuf->st_mode &= ~077; } @@ -1237,11 +1242,11 @@ retval = -EIO; break; } - if (pathinfo.packaged) { + if (pathinfo.packaged && changeOwnerToUserIfPackaged) { stbuf->st_uid = appfs_get_fsuid(); stbuf->st_gid = appfs_get_fsgid(); stbuf->st_mode |= 0200; } @@ -2008,10 +2013,17 @@ 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"); if (getuid() == 0) { fuse_opt_parse(args, NULL, NULL, NULL); fuse_opt_add_arg(args, "-oallow_other"); + + /* + * This should generally be avoided, but if there are security + * concerns suid can be disabled completely on the commandline + */ + fuse_opt_parse(args, NULL, NULL, NULL); + fuse_opt_add_arg(args, "-osuid"); } while ((ch = getopt(argc, argv, "dfshvo:")) != -1) { switch (ch) { case 'v':