diff options
author | Peter Seebach <peter.seebach@windriver.com> | 2012-08-09 18:31:31 -0500 |
---|---|---|
committer | Peter Seebach <peter.seebach@windriver.com> | 2012-08-09 18:31:31 -0500 |
commit | 398a264490713c912b4ce465251a8a82a7905f45 (patch) | |
tree | 1636463f7268d3ffa59a74b8776c2eecefd1d138 | |
parent | 400e1a09e98cc11e18e418ece0a78acfd226b381 (diff) | |
download | pseudo-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.txt | 6 | ||||
-rw-r--r-- | ports/linux/guts/fstat64.c | 13 | ||||
-rw-r--r-- | ports/linux/guts/lstat64.c | 13 | ||||
-rw-r--r-- | ports/linux/guts/stat64.c | 13 | ||||
-rw-r--r-- | ports/linux/pseudo_wrappers.c | 19 | ||||
-rw-r--r-- | ports/linux/wrapfuncs.in | 3 | ||||
-rw-r--r-- | pseudo_client.h | 12 |
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); |