aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Seebach <peter.seebach@windriver.com>2012-08-09 18:31:31 -0500
committerPeter Seebach <peter.seebach@windriver.com>2012-08-09 18:31:31 -0500
commit398a264490713c912b4ce465251a8a82a7905f45 (patch)
tree1636463f7268d3ffa59a74b8776c2eecefd1d138
parent400e1a09e98cc11e18e418ece0a78acfd226b381 (diff)
downloadpseudo-398a264490713c912b4ce465251a8a82a7905f45.tar.gz
pseudo-398a264490713c912b4ce465251a8a82a7905f45.tar.bz2
pseudo-398a264490713c912b4ce465251a8a82a7905f45.zip
Fix up chroot damage caused by PSEUDO_STATBUF fixpseudo-1.4.1PSEUDO_1_4_1
The PSEUDO_STATBUF change (allowing operations on files over 2GB even on 32-bit systems) introduced a subtle bug; by calling stat64() rather than real_stat(), pseudo stopped handling chrooted paths well. In most cases, this was fine, but in the specific case of a rename, where the stat buffers for the various parts were actually used, it wasn't. Of particular note, pseudo could end up creating links which had stack garbage for their stat buffs, because it assumed that if the rename operation succeeded, the stat operations must have succeeded. Of course, there is no real_stat64 in the Linux port, because there's no need for it; most code is calling __xstat64 or some relative thereof, and even if you did really call stat64, it'd end up routed there anyway. So we add that so that it can be used for calls and we don't have to encode Linux-specific magic about __xstat into the generic header.
-rw-r--r--ChangeLog.txt6
-rw-r--r--ports/linux/guts/fstat64.c13
-rw-r--r--ports/linux/guts/lstat64.c13
-rw-r--r--ports/linux/guts/stat64.c13
-rw-r--r--ports/linux/pseudo_wrappers.c19
-rw-r--r--ports/linux/wrapfuncs.in3
-rw-r--r--pseudo_client.h12
7 files changed, 71 insertions, 8 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index de1ff31..906d5cc 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,3 +1,9 @@
+2012-08-09:
+ * (seebs) base_stat should be real_stat64, not stat64
+ * (seebs) add stat64/lstat64/fstat64 wrappers to Linux (not
+ previously needed because the libc versions call stuff we
+ already wrap).
+
2012-08-02:
* (seebs) fix some Darwin-specific bitrot for clang/llvm.
* (seebs) Drop the _plain thing, convert unix/guts/* to use
diff --git a/ports/linux/guts/fstat64.c b/ports/linux/guts/fstat64.c
new file mode 100644
index 0000000..4a759f7
--- /dev/null
+++ b/ports/linux/guts/fstat64.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2012 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int fstat64(int fd, struct stat *buf)
+ * int rc = -1;
+ */
+
+ rc = wrap___fxstat64(_STAT_VER, fd, buf);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/linux/guts/lstat64.c b/ports/linux/guts/lstat64.c
new file mode 100644
index 0000000..94eb60f
--- /dev/null
+++ b/ports/linux/guts/lstat64.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2012 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int lstat64(const char *path, struct stat *buf)
+ * int rc = -1;
+ */
+
+ rc = wrap___fxstatat64(_STAT_VER, AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/linux/guts/stat64.c b/ports/linux/guts/stat64.c
new file mode 100644
index 0000000..53dd156
--- /dev/null
+++ b/ports/linux/guts/stat64.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2012 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int stat64(const char *path, struct stat *buf)
+ * int rc = -1;
+ */
+
+ rc = wrap___fxstatat64(_STAT_VER, AT_FDCWD, path, buf, 0);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/linux/pseudo_wrappers.c b/ports/linux/pseudo_wrappers.c
index 7d3fcd5..26b29b0 100644
--- a/ports/linux/pseudo_wrappers.c
+++ b/ports/linux/pseudo_wrappers.c
@@ -1,6 +1,6 @@
-
/* the unix port wants to know that real_stat() and
- * friends exist. So they do.
+ * friends exist. So they do. And because the Linux
+ * port really uses stat64 for those...
*/
int
pseudo_stat(const char *path, struct stat *buf) {
@@ -16,3 +16,18 @@ int
pseudo_fstat(int fd, struct stat *buf) {
return real___fxstat(_STAT_VER, fd, buf);
}
+
+int
+pseudo_stat64(const char *path, struct stat64 *buf) {
+ return real___xstat64(_STAT_VER, path, buf);
+}
+
+int
+pseudo_lstat64(const char *path, struct stat64 *buf) {
+ return real___lxstat64(_STAT_VER, path, buf);
+}
+
+int
+pseudo_fstat64(int fd, struct stat64 *buf) {
+ return real___fxstat64(_STAT_VER, fd, buf);
+}
diff --git a/ports/linux/wrapfuncs.in b/ports/linux/wrapfuncs.in
index 2dab39d..1ffdb3a 100644
--- a/ports/linux/wrapfuncs.in
+++ b/ports/linux/wrapfuncs.in
@@ -34,6 +34,9 @@ int creat64(const char *path, mode_t mode);
int stat(const char *path, struct stat *buf); /* real_func=pseudo_stat */
int lstat(const char *path, struct stat *buf); /* real_func=pseudo_lstat */
int fstat(int fd, struct stat *buf); /* real_func=pseudo_fstat */
+int stat64(const char *path, struct stat64 *buf); /* real_func=pseudo_stat64 */
+int lstat64(const char *path, struct stat64 *buf); /* real_func=pseudo_lstat64 */
+int fstat64(int fd, struct stat64 *buf); /* real_func=pseudo_fstat64 */
int __xstat64(int ver, const char *path, struct stat64 *buf);
int __lxstat64(int ver, const char *path, struct stat64 *buf); /* flags=AT_SYMLINK_NOFOLLOW */
int __fxstat64(int ver, int fd, struct stat64 *buf);
diff --git a/pseudo_client.h b/pseudo_client.h
index 80880b4..f36a772 100644
--- a/pseudo_client.h
+++ b/pseudo_client.h
@@ -19,14 +19,14 @@
*/
extern pseudo_msg_t *pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path, const PSEUDO_STATBUF *buf, ...);
#if PSEUDO_STATBUF_64
-#define base_lstat lstat64
-#define base_fstat fstat64
-#define base_stat stat64
+#define base_lstat real_lstat64
+#define base_fstat real_fstat64
+#define base_stat real_stat64
#define base_fstatat(dirfd, path, buf, flags) real___fxstatat64(_STAT_VER, dirfd, path, buf, flags)
#else
-#define base_lstat lstat
-#define base_fstat fstat
-#define base_stat stat
+#define base_lstat real_lstat
+#define base_fstat real_fstat
+#define base_stat real_stat
#define base_fstatat(dirfd, path, buf, flags) real___fxstatat(_STAT_VER, dirfd, path, buf, flags)
#endif
extern void pseudo_antimagic(void);