aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Seebach <peter.seebach@windriver.com>2015-08-21 20:26:42 -0500
committerPeter Seebach <peter.seebach@windriver.com>2015-08-24 12:01:52 -0500
commit5de87663775e46aed24b15a894491413513a5d92 (patch)
tree69da72fec4427bfc4be8eea89744669668ecd9f4
parentcb1326a6f3f802405d873b6c0e4cac3207457f32 (diff)
downloadpseudo-5de87663775e46aed24b15a894491413513a5d92.tar.gz
pseudo-5de87663775e46aed24b15a894491413513a5d92.tar.bz2
pseudo-5de87663775e46aed24b15a894491413513a5d92.zip
xattrdb bug fixes
When xattr emulation is used to store extended attributes, dummy entries get made in the db using whatever UID/GID were in the real stat buffer if no entry already existed. Change these to -1, and treat -1 uid/gid as a missing entry for stat purposes. xattrdb was not merging existing uid/gid values. Change this by loading existing values to merge them in when executing chown/chmod commands. Newly-created files could end up with a filesystem mode of 0 if you used umask, but this breaks xattrdb. Signed-off-by: Peter Seebach <peter.seebach@windriver.com>
-rw-r--r--ChangeLog.txt9
-rw-r--r--ports/darwin/guts/open.c1
-rw-r--r--ports/linux/guts/fopen64.c1
-rw-r--r--ports/linux/guts/freopen64.c1
-rw-r--r--ports/linux/guts/mkstemp64.c1
-rw-r--r--ports/linux/guts/openat.c1
-rw-r--r--ports/unix/guts/fopen.c1
-rw-r--r--ports/unix/guts/freopen.c1
-rw-r--r--ports/unix/guts/mkstemp.c1
-rw-r--r--pseudo_client.c92
10 files changed, 82 insertions, 27 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 3a9b9e2..8f2afed 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,3 +1,12 @@
+2015-08-22:
+ * (seebs) Prevent files from getting created with real filesystem
+ mode 0, even with umask.
+ * (seebs) xattrdb logic fixes.
+
+2015-08-21:
+ * (seebs) don't put incorrect host UIDs in dummy entries in db.
+ * (seebs) merge existing values for chown/chmod with xattrdb.
+
2015-08-20:
* (seebs) don't send open/exec messages unless server is logging.
diff --git a/ports/darwin/guts/open.c b/ports/darwin/guts/open.c
index afe19a2..0979c54 100644
--- a/ports/darwin/guts/open.c
+++ b/ports/darwin/guts/open.c
@@ -41,6 +41,7 @@
if (stat_rc != -1) {
buf.st_mode = PSEUDO_DB_MODE(buf.st_mode, mode);
if (!existed) {
+ real_fchmod(rc, PSEUDO_FS_MODE(0600, 0));
pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf);
}
pseudo_client_op(OP_OPEN, PSEUDO_ACCESS(flags), rc, -1, path, &buf);
diff --git a/ports/linux/guts/fopen64.c b/ports/linux/guts/fopen64.c
index ac3fde1..32539ea 100644
--- a/ports/linux/guts/fopen64.c
+++ b/ports/linux/guts/fopen64.c
@@ -20,6 +20,7 @@
pseudo_debug(PDBGF_FILE, "fopen64 '%s': fd %d <FILE %p>\n", path, fd, (void *) rc);
if (real___fxstat64(_STAT_VER, fd, &buf) != -1) {
if (!existed) {
+ real_fchmod(fd, PSEUDO_FS_MODE(0600, 0));
pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf);
}
pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, &buf);
diff --git a/ports/linux/guts/freopen64.c b/ports/linux/guts/freopen64.c
index bb69b34..b6ff0a6 100644
--- a/ports/linux/guts/freopen64.c
+++ b/ports/linux/guts/freopen64.c
@@ -19,6 +19,7 @@
pseudo_debug(PDBGF_FILE, "freopen64 '%s': fd %d\n", path, fd);
if (real___fxstat64(_STAT_VER, fd, &buf) != -1) {
if (!existed) {
+ real_fchmod(fd, PSEUDO_FS_MODE(0600, 0));
pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf);
}
pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, &buf);
diff --git a/ports/linux/guts/mkstemp64.c b/ports/linux/guts/mkstemp64.c
index cbeda0e..48be612 100644
--- a/ports/linux/guts/mkstemp64.c
+++ b/ports/linux/guts/mkstemp64.c
@@ -30,6 +30,7 @@
save_errno = errno;
if (real___fxstat64(_STAT_VER, rc, &buf) != -1) {
+ real_fchmod(rc, PSEUDO_FS_MODE(0600, 0));
pseudo_client_op(OP_CREAT, 0, -1, -1, tmp_template, &buf);
pseudo_client_op(OP_OPEN, PSA_READ | PSA_WRITE, rc, -1, tmp_template, &buf);
} else {
diff --git a/ports/linux/guts/openat.c b/ports/linux/guts/openat.c
index 87fa466..338bd45 100644
--- a/ports/linux/guts/openat.c
+++ b/ports/linux/guts/openat.c
@@ -75,6 +75,7 @@
if (stat_rc != -1) {
buf.st_mode = PSEUDO_DB_MODE(buf.st_mode, mode);
if (!existed) {
+ real_fchmod(rc, PSEUDO_FS_MODE(0600, 0));
pseudo_client_op(OP_CREAT, 0, -1, dirfd, path, &buf);
}
pseudo_client_op(OP_OPEN, PSEUDO_ACCESS(flags), rc, dirfd, path, &buf);
diff --git a/ports/unix/guts/fopen.c b/ports/unix/guts/fopen.c
index de940f5..4214980 100644
--- a/ports/unix/guts/fopen.c
+++ b/ports/unix/guts/fopen.c
@@ -19,6 +19,7 @@
pseudo_debug(PDBGF_OP, "fopen '%s': fd %d <FILE %p>\n", path, fd, (void *) rc);
if (base_fstat(fd, &buf) != -1) {
if (!existed) {
+ real_fchmod(fd, PSEUDO_FS_MODE(0600, 0));
pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf);
}
pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, &buf);
diff --git a/ports/unix/guts/freopen.c b/ports/unix/guts/freopen.c
index 45ca135..09219be 100644
--- a/ports/unix/guts/freopen.c
+++ b/ports/unix/guts/freopen.c
@@ -19,6 +19,7 @@
pseudo_debug(PDBGF_OP, "freopen '%s': fd %d\n", path, fd);
if (base_fstat(fd, &buf) != -1) {
if (!existed) {
+ real_fchmod(fd, PSEUDO_FS_MODE(0600, 0));
pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf);
}
pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, &buf);
diff --git a/ports/unix/guts/mkstemp.c b/ports/unix/guts/mkstemp.c
index 315bec8..1e2b026 100644
--- a/ports/unix/guts/mkstemp.c
+++ b/ports/unix/guts/mkstemp.c
@@ -30,6 +30,7 @@
save_errno = errno;
if (base_fstat(rc, &buf) != -1) {
+ real_fchmod(rc, PSEUDO_FS_MODE(0600, 0));
pseudo_client_op(OP_CREAT, 0, -1, -1, tmp_template, &buf);
pseudo_client_op(OP_OPEN, PSA_READ | PSA_WRITE, rc, -1, tmp_template, &buf);
} else {
diff --git a/pseudo_client.c b/pseudo_client.c
index 8581c85..bccd3e1 100644
--- a/pseudo_client.c
+++ b/pseudo_client.c
@@ -1441,39 +1441,77 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
}
#ifdef PSEUDO_XATTRDB
- /* maybe use xattr instead */
- /* note: if we use xattr, logging won't work reliably
- * because the server won't get messages if these work.
- */
- switch (op) {
- case OP_CHMOD:
- case OP_CREAT:
- case OP_FCHMOD:
- case OP_MKDIR:
- case OP_MKNOD:
- {
- /* use magic uid/gid */
- struct stat64 bufcopy;
+ if (buf) {
+ struct stat64 bufcopy = *buf;
+ int do_save = 0;
+ /* maybe use xattr instead */
+ /* note: if we use xattr, logging won't work reliably
+ * because the server won't get messages if these work.
+ */
+ switch (op) {
+ case OP_CHMOD:
+ case OP_FCHMOD:
+ case OP_CHOWN:
+ case OP_FCHOWN:
+ /* for these, we want to start with the existing db
+ * values.
+ */
bufcopy = *buf;
+ result = pseudo_xattrdb_load(fd, path, buf);
+ if (result && result->result == RESULT_SUCCEED) {
+ pseudo_debug(PDBGF_XATTR, "merging existing values for xattr\n");
+ switch (op) {
+ case OP_CHMOD:
+ case OP_FCHMOD:
+ bufcopy.st_uid = result->uid;
+ bufcopy.st_gid = result->gid;
+ break;
+ case OP_CHOWN:
+ case OP_FCHOWN:
+ bufcopy.st_rdev = result->rdev;
+ bufcopy.st_mode = result->mode;
+ break;
+ default:
+ break;
+ }
+
+ } else {
+ switch (op) {
+ case OP_CHMOD:
+ case OP_FCHMOD:
+ bufcopy.st_uid = pseudo_fuid;
+ bufcopy.st_gid = pseudo_fgid;
+ break;
+ default:
+ break;
+ }
+ }
+ result = NULL;
+ do_save = 1;
+ break;
+ case OP_CREAT:
+ case OP_MKDIR:
+ case OP_MKNOD:
bufcopy.st_uid = pseudo_fuid;
bufcopy.st_gid = pseudo_fgid;
+ do_save = 1;
+ break;
+ case OP_LINK:
+ do_save = 1;
+ break;
+ case OP_FSTAT:
+ case OP_STAT:
+ result = pseudo_xattrdb_load(fd, path, buf);
+ break;
+ default:
+ break;
+ }
+ if (do_save) {
result = pseudo_xattrdb_save(fd, path, &bufcopy);
}
- break;
- case OP_CHOWN:
- case OP_FCHOWN:
- case OP_LINK:
- result = pseudo_xattrdb_save(fd, path, buf);
- break;
- case OP_FSTAT:
- case OP_STAT:
- result = pseudo_xattrdb_load(fd, path, buf);
- break;
- default:
- break;
+ if (result)
+ goto skip_path;
}
- if (result)
- goto skip_path;
#endif
if (op == OP_RENAME) {