diff options
-rw-r--r-- | pkgs/build-support/libredirect/libredirect.c | 5 | ||||
-rw-r--r-- | pkgs/build-support/libredirect/test.c | 12 |
2 files changed, 16 insertions, 1 deletions
diff --git a/pkgs/build-support/libredirect/libredirect.c b/pkgs/build-support/libredirect/libredirect.c index 19211a813eb84..fdbdcb6ebb86f 100644 --- a/pkgs/build-support/libredirect/libredirect.c +++ b/pkgs/build-support/libredirect/libredirect.c @@ -70,9 +70,12 @@ static void init() } -static const char * rewrite(const char * path, char * buf) +static const char * rewrite(const char * volatile path, char * buf) { + // Marking the path volatile is needed so the the following check isn't + // optimized away by the compiler. if (path == NULL) return path; + for (int n = 0; n < nrRedirects; ++n) { int len = strlen(from[n]); if (strncmp(path, from[n], len) != 0) continue; diff --git a/pkgs/build-support/libredirect/test.c b/pkgs/build-support/libredirect/test.c index 7dd384ae3ed7e..20b27759f019f 100644 --- a/pkgs/build-support/libredirect/test.c +++ b/pkgs/build-support/libredirect/test.c @@ -45,6 +45,17 @@ void test_subprocess(void) { assert(system(SUBTEST) == 0); } +void test_stat_with_null_path(void) { + // This checks whether the compiler optimizes away the null pointer check + // on the path passed to stat(). If that's the case, the following code + // should segfault. + struct stat buf; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnonnull" + stat(NULL, &buf); +#pragma GCC diagnostic pop +} + void assert_mktemp_path( const char * orig_prefix, const char * orig_suffix, @@ -147,6 +158,7 @@ int main(int argc, char *argv[]) test_spawn(); test_system(); + test_stat_with_null_path(); // Only run subprocess if no arguments are given // as the subprocess will be called without argument |