|
@@ -1,264 +0,0 @@
|
|
|
-commit 7e67d082737b3df4788caf85fedd607b3acd9786
|
|
|
-Author: Peter Seebach <peter.seebach@windriver.com>
|
|
|
-Date: Fri May 16 15:53:06 2014 -0500
|
|
|
-
|
|
|
- permissions updates: improve fchmodat, mask out write bits
|
|
|
-
|
|
|
- Upstream-Status: Backport of several patches from 1.6 branch,
|
|
|
- combined.
|
|
|
-
|
|
|
- Backport from pseudo 1.6 of improvements to fchmodat (handle
|
|
|
- AT_SYMLINK_NOFOLLOW by rejecting it if the host system does,
|
|
|
- to make GNU tar happier), also mask out write bits from filesystem
|
|
|
- modes to avoid security problems.
|
|
|
-
|
|
|
- Also start tracking umask so we can use the right modes for
|
|
|
- open, mkdir, and mknod.
|
|
|
-
|
|
|
- The 1.6 patches are:
|
|
|
-
|
|
|
- 87c53ea58befef48677846693aab445df1850e16
|
|
|
- 3c716e0bab4f0cfe4be84caa9ce5fd5e3f5e2a23
|
|
|
- c98e4f43b5d6499748a5057134408f4ba4854fb4
|
|
|
- 2f71a021b725c1aa415439209a89327f0b997d02
|
|
|
- 14925786b55202d8147b0af719038e8a23ef73c0
|
|
|
-
|
|
|
-diff --git a/ChangeLog.txt b/ChangeLog.txt
|
|
|
-index 113f675..cc966ce 100644
|
|
|
---- a/ChangeLog.txt
|
|
|
-+++ b/ChangeLog.txt
|
|
|
-@@ -1,3 +1,18 @@
|
|
|
-+2014-05-27:
|
|
|
-+ * (seebs) start noticing umask, mask it out from open or mkdir
|
|
|
-+ calls rather than relying on underlying open/mkdir to do it.
|
|
|
-+
|
|
|
-+2014-05-16:
|
|
|
-+ * (seebs) fchmodat: don't drop flags, report failures, to improve
|
|
|
-+ compatibility/consistency. Cache the knowledge that
|
|
|
-+ AT_SYMLINK_NOFOLLOW gets ENOTSUP.
|
|
|
-+ * (seebs) mask out group/other write bits in real filesystem to
|
|
|
-+ reduce risks when assembling a rootfs including world-writeable
|
|
|
-+ directories.
|
|
|
-+
|
|
|
-+2014-05-15:
|
|
|
-+ * (seebs) drop flags when calling fchmodat() to appease GNU tar.
|
|
|
-+
|
|
|
- 2013-02-27:
|
|
|
- * (seebs) Oh, hey, what if I took out my debug messages?
|
|
|
- * (seebs) update docs a bit to reduce bitrot
|
|
|
-diff --git a/makewrappers b/makewrappers
|
|
|
-index e87cc56..0127766 100755
|
|
|
---- a/makewrappers
|
|
|
-+++ b/makewrappers
|
|
|
-@@ -204,6 +204,7 @@ class Function:
|
|
|
- 'uid_t': '0',
|
|
|
- 'int': '-1',
|
|
|
- 'long': '-1',
|
|
|
-+ 'mode_t': '0',
|
|
|
- 'ssize_t': '-1'
|
|
|
- }
|
|
|
-
|
|
|
-diff --git a/ports/darwin/guts/open.c b/ports/darwin/guts/open.c
|
|
|
-index c66cc15..520bb70 100644
|
|
|
---- a/ports/darwin/guts/open.c
|
|
|
-+++ b/ports/darwin/guts/open.c
|
|
|
-@@ -9,6 +9,9 @@
|
|
|
- struct stat buf = { };
|
|
|
- int existed = 1;
|
|
|
- int save_errno;
|
|
|
-+
|
|
|
-+ /* mask out mode bits appropriately */
|
|
|
-+ mode = mode & ~pseudo_umask;
|
|
|
- #ifdef PSEUDO_FORCE_ASYNCH
|
|
|
- flags &= ~O_SYNC;
|
|
|
- #endif
|
|
|
-diff --git a/ports/linux/guts/__xmknodat.c b/ports/linux/guts/__xmknodat.c
|
|
|
-index 59b4f2f..0888b8a 100644
|
|
|
---- a/ports/linux/guts/__xmknodat.c
|
|
|
-+++ b/ports/linux/guts/__xmknodat.c
|
|
|
-@@ -9,6 +9,9 @@
|
|
|
- pseudo_msg_t *msg;
|
|
|
- struct stat64 buf;
|
|
|
-
|
|
|
-+ /* mask out mode bits appropriately */
|
|
|
-+ mode = mode & ~pseudo_umask;
|
|
|
-+
|
|
|
- /* we don't use underlying call, so _ver is irrelevant to us */
|
|
|
- (void) ver;
|
|
|
-
|
|
|
-diff --git a/ports/linux/guts/openat.c b/ports/linux/guts/openat.c
|
|
|
-index 8460073..4053549 100644
|
|
|
---- a/ports/linux/guts/openat.c
|
|
|
-+++ b/ports/linux/guts/openat.c
|
|
|
-@@ -10,6 +10,9 @@
|
|
|
- int existed = 1;
|
|
|
- int save_errno;
|
|
|
-
|
|
|
-+ /* mask out mode bits appropriately */
|
|
|
-+ mode = mode & ~pseudo_umask;
|
|
|
-+
|
|
|
- #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
|
|
|
- if (dirfd != AT_FDCWD) {
|
|
|
- errno = ENOSYS;
|
|
|
-diff --git a/ports/unix/guts/fchmodat.c b/ports/unix/guts/fchmodat.c
|
|
|
-index 59a92ce..69a953c 100644
|
|
|
---- a/ports/unix/guts/fchmodat.c
|
|
|
-+++ b/ports/unix/guts/fchmodat.c
|
|
|
-@@ -8,6 +8,7 @@
|
|
|
- */
|
|
|
- PSEUDO_STATBUF buf;
|
|
|
- int save_errno = errno;
|
|
|
-+ static int picky_fchmodat = 0;
|
|
|
-
|
|
|
- #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
|
|
|
- if (dirfd != AT_FDCWD) {
|
|
|
-@@ -15,6 +16,16 @@
|
|
|
- return -1;
|
|
|
- }
|
|
|
- if (flags & AT_SYMLINK_NOFOLLOW) {
|
|
|
-+ /* Linux, as of this writing, will always reject this.
|
|
|
-+ * GNU tar relies on getting the rejection. To cut down
|
|
|
-+ * on traffic, we check for the failure, and if we saw
|
|
|
-+ * a failure previously, we reject it right away and tell
|
|
|
-+ * the caller to retry.
|
|
|
-+ */
|
|
|
-+ if (picky_fchmodat) {
|
|
|
-+ errno = ENOTSUP;
|
|
|
-+ return -1;
|
|
|
-+ }
|
|
|
- rc = base_lstat(path, &buf);
|
|
|
- } else {
|
|
|
- rc = base_stat(path, &buf);
|
|
|
-@@ -50,13 +61,22 @@
|
|
|
-
|
|
|
- /* user bits added so "root" can always access files. */
|
|
|
- #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
|
|
|
-- /* note: if path was a symlink, and AT_NOFOLLOW_SYMLINKS was
|
|
|
-+ /* note: if path was a symlink, and AT_SYMLINK_NOFOLLOW was
|
|
|
- * specified, we already bailed previously. */
|
|
|
- real_chmod(path, PSEUDO_FS_MODE(mode, S_ISDIR(buf.st_mode)));
|
|
|
- #else
|
|
|
-- real_fchmodat(dirfd, path, PSEUDO_FS_MODE(mode, S_ISDIR(buf.st_mode)), flags);
|
|
|
-+ rc = real_fchmodat(dirfd, path, PSEUDO_FS_MODE(mode, S_ISDIR(buf.st_mode)), flags);
|
|
|
-+ /* AT_SYMLINK_NOFOLLOW isn't supported by fchmodat. GNU tar
|
|
|
-+ * tries to use it anyway, figuring it can just retry if that
|
|
|
-+ * fails. So we want to report that *particular* failure instead
|
|
|
-+ * of doing the fallback.
|
|
|
-+ */
|
|
|
-+ if (rc == -1 && errno == ENOTSUP && (flags & AT_SYMLINK_NOFOLLOW)) {
|
|
|
-+ picky_fchmodat = 1;
|
|
|
-+ return -1;
|
|
|
-+ }
|
|
|
- #endif
|
|
|
-- /* we ignore a failure from underlying fchmod, because pseudo
|
|
|
-+ /* we otherwise ignore failures from underlying fchmod, because pseudo
|
|
|
- * may believe you are permitted to change modes that the filesystem
|
|
|
- * doesn't. Note that we also don't need to know whether the
|
|
|
- * file might be a (pseudo) block device or some such; pseudo
|
|
|
-diff --git a/ports/unix/guts/mkdirat.c b/ports/unix/guts/mkdirat.c
|
|
|
-index e846b70..e0b6af9 100644
|
|
|
---- a/ports/unix/guts/mkdirat.c
|
|
|
-+++ b/ports/unix/guts/mkdirat.c
|
|
|
-@@ -6,11 +6,14 @@
|
|
|
- * wrap_mkdirat(int dirfd, const char *path, mode_t mode) {
|
|
|
- * int rc = -1;
|
|
|
- */
|
|
|
-+ /* mask out mode bits appropriately */
|
|
|
-+ mode = mode & ~pseudo_umask;
|
|
|
- #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
|
|
|
- if (dirfd != AT_FDCWD) {
|
|
|
- errno = ENOSYS;
|
|
|
- return -1;
|
|
|
- }
|
|
|
-+
|
|
|
- rc = real_mkdir(path, PSEUDO_FS_MODE(mode, 1));
|
|
|
- #else
|
|
|
- rc = real_mkdirat(dirfd, path, PSEUDO_FS_MODE(mode, 1));
|
|
|
-diff --git a/ports/unix/guts/mknodat.c b/ports/unix/guts/mknodat.c
|
|
|
-index 6fd5b42..5d8d47c 100644
|
|
|
---- a/ports/unix/guts/mknodat.c
|
|
|
-+++ b/ports/unix/guts/mknodat.c
|
|
|
-@@ -10,6 +10,9 @@
|
|
|
- PSEUDO_STATBUF buf;
|
|
|
- int save_errno = errno;
|
|
|
-
|
|
|
-+ /* mask out mode bits appropriately */
|
|
|
-+ mode = mode & ~pseudo_umask;
|
|
|
-+
|
|
|
- #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
|
|
|
- if (dirfd != AT_FDCWD) {
|
|
|
- errno = ENOSYS;
|
|
|
-diff --git a/ports/unix/guts/umask.c b/ports/unix/guts/umask.c
|
|
|
-new file mode 100644
|
|
|
-index 0000000..6b060d3
|
|
|
---- /dev/null
|
|
|
-+++ b/ports/unix/guts/umask.c
|
|
|
-@@ -0,0 +1,14 @@
|
|
|
-+/*
|
|
|
-+ * Copyright (c) 2014 Wind River Systems; see
|
|
|
-+ * guts/COPYRIGHT for information.
|
|
|
-+ *
|
|
|
-+ * mode_t umask(mode_t mask)
|
|
|
-+ * mode_t rc = 0;
|
|
|
-+ */
|
|
|
-+
|
|
|
-+ pseudo_umask = mask;
|
|
|
-+ rc = real_umask(mask);
|
|
|
-+
|
|
|
-+/* return rc;
|
|
|
-+ * }
|
|
|
-+ */
|
|
|
-diff --git a/ports/unix/wrapfuncs.in b/ports/unix/wrapfuncs.in
|
|
|
-index 8460a65..e0e9739 100644
|
|
|
---- a/ports/unix/wrapfuncs.in
|
|
|
-+++ b/ports/unix/wrapfuncs.in
|
|
|
-@@ -67,3 +67,4 @@ void sync(void); /* async_skip= */
|
|
|
- int syncfs(int fd); /* async_skip=0 */
|
|
|
- int sync_file_range(int fd, off64_t offset, off64_t nbytes, unsigned int flags); /* async_skip=0 */
|
|
|
- int msync(void *addr, size_t length, int flags); /* async_skip=0 */
|
|
|
-+mode_t umask(mode_t mask);
|
|
|
-diff --git a/pseudo_client.c b/pseudo_client.c
|
|
|
-index b6d11a6..535c810 100644
|
|
|
---- a/pseudo_client.c
|
|
|
-+++ b/pseudo_client.c
|
|
|
-@@ -71,6 +71,8 @@ int pseudo_disabled = 0;
|
|
|
- int pseudo_allow_fsync = 0;
|
|
|
- static int pseudo_local_only = 0;
|
|
|
-
|
|
|
-+int pseudo_umask = 022;
|
|
|
-+
|
|
|
- static char **fd_paths = NULL;
|
|
|
- static int nfds = 0;
|
|
|
- static int messages = 0;
|
|
|
-@@ -219,6 +221,9 @@ pseudo_init_client(void) {
|
|
|
- if (!pseudo_disabled && !pseudo_inited) {
|
|
|
- char *pseudo_path = 0;
|
|
|
-
|
|
|
-+ pseudo_umask = umask(022);
|
|
|
-+ umask(pseudo_umask);
|
|
|
-+
|
|
|
- pseudo_path = pseudo_prefix_path(NULL);
|
|
|
- if (pseudo_prefix_dir_fd == -1) {
|
|
|
- if (pseudo_path) {
|
|
|
-diff --git a/pseudo_client.h b/pseudo_client.h
|
|
|
-index f36a772..5bf820e 100644
|
|
|
---- a/pseudo_client.h
|
|
|
-+++ b/pseudo_client.h
|
|
|
-@@ -72,6 +72,8 @@ extern char *pseudo_passwd;
|
|
|
- extern size_t pseudo_chroot_len;
|
|
|
- extern int pseudo_nosymlinkexp;
|
|
|
-
|
|
|
-+extern int pseudo_umask;
|
|
|
-+
|
|
|
- /* Root can read and write files, and enter directories which have no
|
|
|
- * read, write, or execute permissions. (But can't execute files without
|
|
|
- * execute permissions!)
|
|
|
-@@ -85,6 +87,6 @@ extern int pseudo_nosymlinkexp;
|
|
|
- * None of this will behave very sensibly if umask has 0700 bits in it;
|
|
|
- * this is a known limitation.
|
|
|
- */
|
|
|
--#define PSEUDO_FS_MODE(mode, isdir) ((mode) | S_IRUSR | S_IWUSR | ((isdir) ? S_IXUSR : 0))
|
|
|
--#define PSEUDO_DB_MODE(fs_mode, user_mode) (((fs_mode) & ~0700) | ((user_mode & 0700)))
|
|
|
-+#define PSEUDO_FS_MODE(mode, isdir) (((mode) | S_IRUSR | S_IWUSR | ((isdir) ? S_IXUSR : 0)) & ~(S_IWGRP | S_IWOTH))
|
|
|
-+#define PSEUDO_DB_MODE(fs_mode, user_mode) (((fs_mode) & ~0722) | ((user_mode & 0722)))
|
|
|
-
|