Skip to content

Commit

Permalink
Don't try to read section headers if they're not present.
Browse files Browse the repository at this point in the history
  • Loading branch information
peadar committed Sep 30, 2023
1 parent d06105a commit 698f3e6
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 43 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ endif()
set(VERSION_TAG ${GIT_TAG} CACHE STRING "Version tag (defaults to git commit)")
message(STATUS "Version: ${VERSION_TAG}")

add_definitions(-DVERSION=${VERSION_TAG} -D_FORTIFY_SOURCE=2)
add_definitions(-DVERSION=${VERSION_TAG})

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS ON)
Expand Down
93 changes: 53 additions & 40 deletions elf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -223,50 +223,63 @@ Object::Object(ImageCache &cache, Reader::csptr io_, bool isDebug)
Elf::Off off;
int i;

// If there are too many headers, we need to look in the first section header
// to get the actual count.
int headerCount = elfHeader.e_shnum == 0 && elfHeader.e_shentsize != 0 ?
1 : elfHeader.e_shnum;

// sectionHeaders.reserve(elfHeader.e_shnum);
for (off = elfHeader.e_shoff, i = 0; i < headerCount; i++) {
sectionHeaders.emplace_back(std::make_unique<Section>(this, off));
if (i == 0 && elfHeader.e_shnum == 0)
headerCount = sectionHeaders[0]->shdr.sh_size;
off += elfHeader.e_shentsize;
}
if (sectionHeaders.size() == 0) {
sectionHeaders.push_back(std::make_unique<Section>());
}

if (elfHeader.e_shstrndx != SHN_UNDEF) {
// Create a mapping from section header names to section headers.
// We need to do this after reading all the section headers, because
// until then we don't have the details of the shstr section
// Make sure the header sections are present in the reader, otherwise, skip.
if (elfHeader.e_shoff < io->size()) {
// If there are too many headers, we need to look in the first section header
// to get the actual count.
//
// We need to deal with the fact that e_shstrndx might be too small
// to hold the index of the string section, and look in sh_link if so.
int shstrSec = elfHeader.e_shstrndx == SHN_XINDEX ?
sectionHeaders[0]->shdr.sh_link :
elfHeader.e_shstrndx;
auto &sshdr = sectionHeaders[shstrSec];
size_t secid = 0;
for (auto &h : sectionHeaders) {
auto name = sshdr->io()->readString(h->shdr.sh_name);
namedSection[name] = secid++;
h->name = name;
int headerCount;
if (elfHeader.e_shnum == 0 && elfHeader.e_shentsize != 0) {
headerCount = 1;
} else {
headerCount = elfHeader.e_shnum;
sectionHeaders.reserve(headerCount);
}

/*
* Load dynamic entries
*/
auto &section = getSection(".dynamic", SHT_DYNAMIC );
if (section) {
ReaderArray<Dyn> content(*section.io());
for (auto dyn : content)
dynamic[dyn.d_tag].push_back(dyn);
for (off = elfHeader.e_shoff, i = 0; i < headerCount; i++) {
sectionHeaders.emplace_back(std::make_unique<Section>(this, off));
if (i == 0 && elfHeader.e_shnum == 0) {
headerCount = sectionHeaders[0]->shdr.sh_size;
sectionHeaders.reserve(headerCount);
}
off += elfHeader.e_shentsize;
}
if (sectionHeaders.size() == 0) {
sectionHeaders.push_back(std::make_unique<Section>());
}
gnu_version = &getSection(".gnu_version", SHT_GNU_versym);

if (elfHeader.e_shstrndx != SHN_UNDEF) {
// Create a mapping from section header names to section headers.
// We need to do this after reading all the section headers, because
// until then we don't have the details of the shstr section
//
// We need to deal with the fact that e_shstrndx might be too small
// to hold the index of the string section, and look in sh_link if so.
int shstrSec = elfHeader.e_shstrndx == SHN_XINDEX ?
sectionHeaders[0]->shdr.sh_link :
elfHeader.e_shstrndx;
auto &sshdr = sectionHeaders[shstrSec];
size_t secid = 0;
for (auto &h : sectionHeaders) {
auto name = sshdr->io()->readString(h->shdr.sh_name);
namedSection[name] = secid++;
h->name = name;
}

/*
* Load dynamic entries
*/
auto &section = getSection(".dynamic", SHT_DYNAMIC );
if (section) {
ReaderArray<Dyn> content(*section.io());
for (auto dyn : content)
dynamic[dyn.d_tag].push_back(dyn);
}
gnu_version = &getSection(".gnu_version", SHT_GNU_versym);
}
} else {
// leave a null section no matter what.
sectionHeaders.push_back(std::make_unique<Section>());
}
}

Expand Down
6 changes: 4 additions & 2 deletions libpstack/proc.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,14 @@ struct Lwp {

struct PrintableFrame;


struct DevNode {
int major;
int minor;
unsigned long inode;
std::string path;
bool operator == (const DevNode &rhs) {
return major == rhs.major && minor == rhs.minor && inode == rhs.inode;
}
};

struct AddressRange {
Expand All @@ -179,7 +181,7 @@ struct AddressRange {
DevNode backing;

enum class Flags { read,write,exec,priv,count, shared };
std::set<Flags> permissions; // PROT_READ/PROT_WRITE/PROT_EXEC
std::set<Flags> permissions;
};

class Process : public ps_prochandle {
Expand Down

0 comments on commit 698f3e6

Please sign in to comment.