fix: crash when running ELF w/ interpreter missing

The function `stat` as defined in `include/x86_64-linux-gnu/sys/stat.h`
marks its arguments as nonnull as in below. This UB causes crash in
release builds with variable `interpreter` assumed to be nonnull. Along
with failing stat returning nonzero value, this ultimately causes
`strlen` to be called with NULL as argument.

Definition of `stat`:
```
extern int stat (const char *__restrict __file,
		 struct stat *__restrict __buf) __THROW __nonnull ((1, 2));
```
Reproduce:
```
> # interp.c is any vaild single file C source
> gcc ./interp.c -Wl,--dynamic-linker=/bad -o interp
> echo './interp' > in.txt
> ./fish < in.txt
'./fish < in.txt' terminated by signal SIGSEGV (Address boundary error)
```

Co-authored-by: Moody Liu <mooodyhunter@outlook.com>
This commit is contained in:
ksyx 2024-01-08 18:31:52 -05:00 committed by Fabian Boehm
parent b91723dab6
commit 001f797f80

View File

@ -463,7 +463,7 @@ void safe_report_exec_error(int err, const char *actual_cmd, const char *const *
const char *interpreter =
get_interpreter(actual_cmd, interpreter_buff, sizeof interpreter_buff);
struct stat buf;
auto statret = stat(interpreter, &buf);
auto statret = !interpreter || stat(interpreter, &buf);
if (interpreter && (0 != statret || access(interpreter, X_OK))) {
// Detect Windows line endings and complain specifically about them.
auto len = strlen(interpreter);