[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