diff options
author | Julien Cristau <jcristau@debian.org> | 2022-09-05 10:32:12 +0200 |
---|---|---|
committer | Lucas De Marchi <lucas.de.marchi@gmail.com> | 2022-09-05 13:35:09 -0700 |
commit | b4d281f962be74adfbae9d7bead6a7352033342c (patch) | |
tree | e0738abdc5cd11f7a27572c4c2d402fad42c51b8 | |
parent | c1fb98a30dae051ab69d23624d1e062d0527527e (diff) | |
download | kmod-b4d281f962be74adfbae9d7bead6a7352033342c.tar.gz |
testsuite: fix override of `stat` on 32-bit architectures
When _FILE_OFFSET_BITS is 64, glibc headers turn `stat` calls into
`stat64`, and our `stat` override into a `stat64` function. However,
because we use dlsym to get the address of libc's `stat`, we end up
calling into the "real" `stat` function, which deals with 32-bit off_t,
and we treat its result as if it were returned from stat64. On most
architectures this seems to have been harmless, but on 32-bit mips,
st_mode's offset in struct stat and struct stat64 are different, so we
read garbage.
To fix this, explicitly unset _FILE_OFFSET_BITS in path.c, to turn off
the redirect magic in glibc headers, and override both the 32-bit and
64-bit functions so each call ends up wrapping the right libc function.
Fixes #16 (https://github.com/kmod-project/kmod/issues/16)
-rw-r--r-- | testsuite/path.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/testsuite/path.c b/testsuite/path.c index fa5fceb..964d33e 100644 --- a/testsuite/path.c +++ b/testsuite/path.c @@ -15,6 +15,10 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ +/* We unset _FILE_OFFSET_BITS here so we can override both stat and stat64 on + * 32-bit architectures and forward each to the right libc function */ +#undef _FILE_OFFSET_BITS + #include <assert.h> #include <dirent.h> #include <dlfcn.h> @@ -183,23 +187,20 @@ TS_EXPORT int prefix ## stat ## suffix (int ver, \ WRAP_1ARG(DIR*, NULL, opendir); WRAP_2ARGS(FILE*, NULL, fopen, const char*); +WRAP_2ARGS(FILE*, NULL, fopen64, const char*); WRAP_2ARGS(int, -1, mkdir, mode_t); WRAP_2ARGS(int, -1, access, int); WRAP_2ARGS(int, -1, stat, struct stat*); WRAP_2ARGS(int, -1, lstat, struct stat*); -#ifndef _FILE_OFFSET_BITS WRAP_2ARGS(int, -1, stat64, struct stat64*); WRAP_2ARGS(int, -1, lstat64, struct stat64*); WRAP_OPEN(64); -#endif WRAP_OPEN(); #ifdef HAVE___XSTAT WRAP_VERSTAT(__x,); WRAP_VERSTAT(__lx,); -#ifndef _FILE_OFFSET_BITS WRAP_VERSTAT(__x,64); WRAP_VERSTAT(__lx,64); #endif -#endif |