diff options
author | 2012-08-09 18:31:31 -0500 | |
---|---|---|
committer | 2012-08-09 18:31:31 -0500 | |
commit | 398a264490713c912b4ce465251a8a82a7905f45 (patch) | |
tree | 1636463f7268d3ffa59a74b8776c2eecefd1d138 /ports | |
parent | 400e1a09e98cc11e18e418ece0a78acfd226b381 (diff) | |
download | pseudo-1.4.1.tar.gz pseudo-1.4.1.tar.bz2 pseudo-1.4.1.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.
Diffstat (limited to 'ports')
-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 |
5 files changed, 59 insertions, 2 deletions
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); |