diff options
author | Sam James <sam@gentoo.org> | 2024-04-23 21:10:18 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2024-09-27 20:03:30 +0200 |
commit | 480a07bd6828285628abbbe3fe8e5e3b25ce1a92 (patch) | |
tree | 97756fcd81612a7cc2c47601367bfd5b8e50564f | |
parent | dbd14c4a42454b61a5474f6243865a6ec113e60b (diff) | |
download | busybox-w32-480a07bd6828285628abbbe3fe8e5e3b25ce1a92.tar.gz busybox-w32-480a07bd6828285628abbbe3fe8e5e3b25ce1a92.tar.bz2 busybox-w32-480a07bd6828285628abbbe3fe8e5e3b25ce1a92.zip |
fixdep: add fstat error handling
When `fstat` fails, `st` is left uninitialised. In our case, Ben Kohler
noticed our release media builds were failing in Gentoo on x86 when building
busybox with occasional SIGBUS. This turned out to be EOVERFLOW (from 32-bit
ino_t) which wasn't being reported because nothing was checking the return value
from `fstat`.
Fix that to avoid UB (use of uninit var) and to give a more friendly
error to the user.
This actually turns out to be fixed already in the kernel from back in
2010 [0] and 2016 [1].
[0] https://github.com/torvalds/linux/commit/a3ba81131aca243bfecfa78c42edec0cd69f72d6
[1] https://github.com/torvalds/linux/commit/46fe94ad18aa7ce6b3dad8c035fb538942020f2b
Reported-by: Ben Kohler <bkohler@gentoo.org>
Signed-off-by: Sam James <sam@gentoo.org>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | scripts/basic/fixdep.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index 66be73aad..071c3b407 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c | |||
@@ -105,6 +105,7 @@ | |||
105 | #include <sys/types.h> | 105 | #include <sys/types.h> |
106 | #include <sys/stat.h> | 106 | #include <sys/stat.h> |
107 | #include <sys/mman.h> | 107 | #include <sys/mman.h> |
108 | #include <errno.h> | ||
108 | #include <unistd.h> | 109 | #include <unistd.h> |
109 | #include <fcntl.h> | 110 | #include <fcntl.h> |
110 | #include <string.h> | 111 | #include <string.h> |
@@ -292,7 +293,10 @@ void do_config_file(char *filename) | |||
292 | perror(filename); | 293 | perror(filename); |
293 | exit(2); | 294 | exit(2); |
294 | } | 295 | } |
295 | fstat(fd, &st); | 296 | if (fstat(fd, &st) < 0) { |
297 | fprintf(stderr, "fixdep: fstat %s %s\n", filename, strerror(errno)); | ||
298 | exit(2); | ||
299 | } | ||
296 | if (st.st_size == 0) { | 300 | if (st.st_size == 0) { |
297 | close(fd); | 301 | close(fd); |
298 | return; | 302 | return; |
@@ -368,7 +372,10 @@ void print_deps(void) | |||
368 | perror(depfile); | 372 | perror(depfile); |
369 | exit(2); | 373 | exit(2); |
370 | } | 374 | } |
371 | fstat(fd, &st); | 375 | if (fstat(fd, &st) < 0) { |
376 | fprintf(stderr, "fixdep: fstat %s %s\n", depfile, strerror(errno)); | ||
377 | exit(2); | ||
378 | } | ||
372 | if (st.st_size == 0) { | 379 | if (st.st_size == 0) { |
373 | fprintf(stderr,"fixdep: %s is empty\n",depfile); | 380 | fprintf(stderr,"fixdep: %s is empty\n",depfile); |
374 | close(fd); | 381 | close(fd); |