When running crash on a live kernel without specifying /proc/kcore as an
explicit argument, crash prints an unexpected error message during startup:
/proc/kcore: read: Bad file descriptor
Commit ad427b7f8ffc ("fix eheader overflow") replaced BCOPY with
read(fd, pkd->elf_header, pkd->header_size) to support large ELF headers.
However, when kcore_fd == UNUSED, fd was already closed immediately after
lseek(fd, 0, SEEK_SET) before read():
if (lseek(fd, 0, SEEK_SET) != 0) {
sprintf(buf, "/proc/kcore: lseek");
perror(buf);
goto bailout;
}
if (fd != kcore_fd)
close(fd);
This causes the subsequent read(fd, pkd->elf_header, pkd->header_size)
to fail with EBADF.
Move close(fd) to the exit points so that fd remains open until all
reads are complete. Also ensure fd is closed via bailout if e_phoff
validation fails.
Fixes: ad427b7f8ffc ("fix eheader overflow")
Signed-off-by: Curu Wong <prinbra(a)gmail.com>
---
netdump.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/netdump.c b/netdump.c
index 64d4edc..b2cf26d 100644
--- a/netdump.c
+++ b/netdump.c
@@ -4652,13 +4652,10 @@ proc_kcore_init_32(FILE *fp, int kcore_fd)
goto bailout;
}
- if (fd != kcore_fd)
- close(fd);
-
elf32 = (Elf32_Ehdr *)&eheader[0];
if (elf32->e_phoff > sizeof(eheader) - 2 * sizeof(Elf32_Phdr)) {
error(INFO, "/proc/kcore: ELF program header offset too big!\n");
- return FALSE;
+ goto bailout;
}
notes32 = (Elf32_Phdr *)&eheader[elf32->e_phoff];
load32 = notes32 + 1;
@@ -4691,6 +4688,9 @@ proc_kcore_init_32(FILE *fp, int kcore_fd)
kcore_memory_dump(CRASHDEBUG(1) ? fp : pc->nullfp);
+ if (fd != kcore_fd)
+ close(fd);
+
return TRUE;
bailout:
@@ -4730,13 +4730,10 @@ proc_kcore_init_64(FILE *fp, int kcore_fd)
goto bailout;
}
- if (fd != kcore_fd)
- close(fd);
-
elf64 = (Elf64_Ehdr *)&eheader[0];
if (elf64->e_phoff > sizeof(eheader) - 2 * sizeof(Elf64_Phdr)) {
error(INFO, "/proc/kcore: ELF program header offset too big!\n");
- return FALSE;
+ goto bailout;
}
notes64 = (Elf64_Phdr *)&eheader[elf64->e_phoff];
load64 = notes64 + 1;
@@ -4770,6 +4767,9 @@ proc_kcore_init_64(FILE *fp, int kcore_fd)
kcore_memory_dump(CRASHDEBUG(1) ? fp : pc->nullfp);
+ if (fd != kcore_fd)
+ close(fd);
+
return TRUE;
bailout:
--
2.43.7