Commit c07f4bb4 authored by Teng Qin's avatar Teng Qin Committed by Facebook Github Bot

Avoid crash when opening broken file

Summary:
In `folly::symbolizer::ElfFile`, we `mmap` the file and access the file content via `mmap`-ed pointer directly. This is nice and efficient, but causes the whole program crashes on `SIGBUS` is the underlying frile is broken.

This Diff changes the first read of the file, for ELF magic number, to use `read` syscall and check return result, instead of accessing the `mmap`-ed pointer directly. This way APIs like `ElfFile::openNoThrow` would return error instead of crashing if the underlying file is broken.

It still doesn't solve the problem if the file becomes broken between we read the ELF magic number and we read file content with the `mmap`-ed file pointer later. But this is the best effort to check for the case with minimal performance cost.

Reviewed By: yfeldblum

Differential Revision: D9474328

fbshipit-source-id: 969e0323fcb4011e6a080d914452c9215d2fd13c
parent c76d6b8c
......@@ -210,14 +210,25 @@ bool ElfFile::init(const char** msg) {
return false;
}
// Validate ELF magic numbers
if (file_[EI_MAG0] != ELFMAG0 || file_[EI_MAG1] != ELFMAG1 ||
file_[EI_MAG2] != ELFMAG2 || file_[EI_MAG3] != ELFMAG3) {
std::array<char, 5> elfMagBuf = {{0, 0, 0, 0, 0}};
if (::lseek(fd_, 0, SEEK_SET) != 0 || ::read(fd_, elfMagBuf.data(), 4) != 4) {
if (msg) {
*msg = "unable to read ELF file for magic number";
}
return false;
}
if (std::strncmp(elfMagBuf.data(), ELFMAG, sizeof(ELFMAG)) != 0) {
if (msg) {
*msg = "invalid ELF magic";
}
return false;
}
if (::lseek(fd_, 0, SEEK_SET) != 0) {
if (msg) {
*msg = "unable to reset file descriptor after reading ELF magic number";
}
return false;
}
auto& elfHeader = this->elfHeader();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment