[Pkg-libvirt-commits] [libguestfs] 114/165: fuse: UID 0 should override all permissions checks (RHBZ#1106548).

Hilko Bengen bengen at moszumanska.debian.org
Sat Aug 30 08:25:01 UTC 2014


This is an automated email from the git hooks/post-receive script.

bengen pushed a commit to branch experimental
in repository libguestfs.

commit 9b5cdc874784437d7a59bd024043c2abd930b6c3
Author: Richard W.M. Jones <rjones at redhat.com>
Date:   Thu Jun 12 13:28:03 2014 +0100

    fuse: UID 0 should override all permissions checks (RHBZ#1106548).
    
    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 | 55 +++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 39 insertions(+), 16 deletions(-)

diff --git a/src/fuse.c b/src/fuse.c
index dd63729..00f9092 100644
--- a/src/fuse.c
+++ b/src/fuse.c
@@ -296,26 +296,49 @@ mount_local_access (const char *path, int mask)
     return -EROFS;
 
   r = mount_local_getattr (path, &statbuf);
-  if (r < 0 || mask == F_OK)
+  if (r < 0 || mask == F_OK) {
+    debug (g, "%s: mount_local_getattr returned r = %d", path, r);
     return r;
+  }
 
   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;
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-libvirt/libguestfs.git



More information about the Pkg-libvirt-commits mailing list