Previously if you were root, and you tried to change directory into a directory which was not owned by you and not readable (eg. 0700 bin:bin), it would fail.
This doesn't fail on regular directories because when you are root the kernel just ignores permissions. Although libguestfs in general tries not to duplicate kernel code, in the case where we emulate the FUSE access(2) system call, unfortunately we have to do it by stat-ing the object and performing some (half-arsed) heuristics. This commit modifies the FUSE access(2) system call, so root is now able to chdir to any directory. It also adds some debugging so we can debug these complex permissions checks in the field if some other problem arises in future. --- src/fuse.c | 51 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/src/fuse.c b/src/fuse.c index dd63729..292ebee 100644 --- a/src/fuse.c +++ b/src/fuse.c @@ -301,21 +301,42 @@ mount_local_access (const char *path, int mask) fuse = fuse_get_context (); - if (mask & R_OK) - ok = ok && - ( fuse->uid == statbuf.st_uid ? statbuf.st_mode & S_IRUSR - : fuse->gid == statbuf.st_gid ? statbuf.st_mode & S_IRGRP - : statbuf.st_mode & S_IROTH); - if (mask & W_OK) - ok = ok && - ( fuse->uid == statbuf.st_uid ? statbuf.st_mode & S_IWUSR - : fuse->gid == statbuf.st_gid ? statbuf.st_mode & S_IWGRP - : statbuf.st_mode & S_IWOTH); - if (mask & X_OK) - ok = ok && - ( fuse->uid == statbuf.st_uid ? statbuf.st_mode & S_IXUSR - : fuse->gid == statbuf.st_gid ? statbuf.st_mode & S_IXGRP - : statbuf.st_mode & S_IXOTH); + /* Root user should be able to access everything, so only bother + * with these fine-grained tests for non-root. (RHBZ#1106548). + */ + if (fuse->uid != 0) { + if (mask & R_OK) + ok = ok && + ( fuse->uid == statbuf.st_uid ? statbuf.st_mode & S_IRUSR + : fuse->gid == statbuf.st_gid ? statbuf.st_mode & S_IRGRP + : statbuf.st_mode & S_IROTH); + if (mask & W_OK) + ok = ok && + ( fuse->uid == statbuf.st_uid ? statbuf.st_mode & S_IWUSR + : fuse->gid == statbuf.st_gid ? statbuf.st_mode & S_IWGRP + : statbuf.st_mode & S_IWOTH); + if (mask & X_OK) + ok = ok && + ( fuse->uid == statbuf.st_uid ? statbuf.st_mode & S_IXUSR + : fuse->gid == statbuf.st_gid ? statbuf.st_mode & S_IXGRP + : statbuf.st_mode & S_IXOTH); + } + + debug (g, "%s: " + "testing access mask%s%s%s%s: " + "caller UID:GID = %d:%d, " + "file UID:GID = %d:%d, " + "file mode = %o, " + "result = %s", + path, + mask & R_OK ? " R_OK" : "", + mask & W_OK ? " W_OK" : "", + mask & X_OK ? " X_OK" : "", + mask == 0 ? " 0" : "", + fuse->uid, fuse->gid, + statbuf.st_uid, statbuf.st_gid, + statbuf.st_mode, + ok ? "OK" : "EACCESS"); return ok ? 0 : -EACCES; } -- 1.9.0 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs