[Fakeroot-commits] [SCM] fakeroot branch, upstream, updated. debian/1.14.3-200-gb232f8a

Clint Adams clint at debian.org
Tue Aug 23 13:06:34 UTC 2011


The following commit has been merged in the upstream branch:
commit 31a273979c1a2f691fb122e816af100607cd2431
Author: Jonathan Nieder <jrnieder at gmail.com>
Date:   Thu Jun 9 18:22:55 2011 -0500

    Bug#629956: "fakeroot test -w /" has an exit status of 1
    
    Clint Adams wrote:
    > On Thu, Jun 09, 2011 at 04:32:48PM -0500, Jonathan Nieder wrote:
    
    >> I can reproduce it with /usr/bin/test from coreutils 8.5-1 or $sh -c
    >> 'test -w /' for various shells such as posh 0.10.  All use access(2)
    >> as far as I can tell.
    >>
    >> Known problem?
    >
    > Neither access() nor euidaccess() is wrapped.
    
    Makes sense.  How about something along these lines?
    
    Seems to work for "posh -c 'test -w /'", but since this doesn't wrap
    euidaccess() or faccessat(), it's not enough yet for bash, dash, and
    coreutils test.

diff --git a/libfakeroot.c b/libfakeroot.c
index ddde1cf..d6cd757 100644
--- a/libfakeroot.c
+++ b/libfakeroot.c
@@ -94,6 +94,7 @@
 #include <dirent.h>
 #include <errno.h>
 #include <sys/types.h>
+#include <sys/statvfs.h>
 #ifdef HAVE_SYS_ACL_H
 #include <sys/acl.h>
 #endif /* HAVE_SYS_ACL_H */
@@ -101,6 +102,11 @@
 #include <fts.h>
 #endif /* HAVE_FTS_H */
 
+/* ST_NOEXEC is a glibc extension */
+#ifndef ST_NOEXEC
+#define ST_NOEXEC 0
+#endif
+
 #if !HAVE_DECL_SETENV
 extern int setenv (const char *name, const char *value, int replace);
 #endif
@@ -1494,6 +1500,87 @@ int setgroups(SETGROUPS_SIZE_TYPE size, const gid_t *list){
     return 0;
 }
 
+int access(const char *path, int amode) {
+  INT_STRUCT_STAT st;
+  struct statvfs fs_st;
+  uid_t uid;
+  gid_t gid;
+  int r;
+
+  /*
+    Missing pieces:
+    - should run path lookup with permissions of (uid, gid)
+    - capabilities
+    - POSIX acls
+    - restricting write permission to an immutable file
+   */
+
+#ifdef LIBFAKEROOT_DEBUGGING
+  if (fakeroot_debug) {
+    fprintf(stderr, "access path %s\n", path);
+  }
+#endif /* LIBFAKEROOT_DEBUGGING */
+  if (fakeroot_disabled || amode == F_OK)
+    return next_access(path, amode);
+
+  if (amode & ~(R_OK | W_OK | X_OK)) {
+    errno = EINVAL;
+    return -1;
+  }
+
+  r = INT_NEXT_STAT(path, &st);
+  if (r)
+    return r;
+
+  /* Read-only or noexec filesystem? */
+  if (amode & (W_OK | X_OK)) {
+    r = statvfs(path, &fs_st);
+    if (!r && (amode & W_OK) && (fs_st.f_flag & ST_RDONLY)) {
+      errno = EROFS;
+      return -1;
+    }
+    if (!r && (amode & X_OK) && (fs_st.f_flag & ST_NOEXEC)) {
+      errno = EACCES;
+      return -1;
+    }
+    if (r && errno != ENOSYS)
+      return -1;
+  }
+
+  uid = get_faked_uid();
+  gid = get_faked_gid();
+
+  if (uid == st.st_uid) {
+    if (!((amode & R_OK) && !(st.st_mode & S_IRUSR)) &&
+        !((amode & W_OK) && !(st.st_mode & S_IWUSR)) &&
+        !((amode & X_OK) && !(st.st_mode & S_IXUSR)))
+      return 0;
+  } else if (gid == st.st_gid) {
+    if (!((amode & R_OK) && !(st.st_mode & S_IRGRP)) &&
+        !((amode & W_OK) && !(st.st_mode & S_IWGRP)) &&
+        !((amode & X_OK) && !(st.st_mode & S_IXGRP)))
+      return 0;
+  } else {
+    if (!((amode & R_OK) && !(st.st_mode & S_IROTH)) &&
+        !((amode & W_OK) && !(st.st_mode & S_IWOTH)) &&
+        !((amode & X_OK) && !(st.st_mode & S_IXOTH)))
+      return 0;
+  }
+
+  if ((amode & X_OK) && !S_ISDIR(st.st_mode) &&
+      !(st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
+    errno = EACCES;
+    return -1;
+  }
+
+  /* root gets CAP_DAC_OVERRIDE */
+  if (uid == 0)
+    return 0;
+
+  errno = EACCES;
+  return -1;
+}
+
 int fakeroot_disable(int new)
 {
   int old = fakeroot_disabled;
diff --git a/wrapfunc.inp b/wrapfunc.inp
index dd3884e..fb9ab90 100644
--- a/wrapfunc.inp
+++ b/wrapfunc.inp
@@ -124,6 +124,7 @@ setfsgid;gid_t;(gid_t fsgid);(fsgid)
 #endif /* HAVE_SETFSGID */
 initgroups;int;(const char *user, INITGROUPS_SECOND_ARG group);(user, group)
 setgroups;int;(SETGROUPS_SIZE_TYPE size, const gid_t *list);(size, list)
+access;int;(const char *pathname, int mode);(pathname, mode)
 
 #ifdef HAVE_FSTATAT
 #ifdef HAVE_FCHMODAT

-- 
fakeroot



More information about the Fakeroot-commits mailing list