3232#include " src/common/fs/fs_wrapper.h"
3333#include " src/stirling/obj_tools/init.h"
3434
35+ DEFINE_int64 (elf_reader_max_file_size, 0 ,
36+ " Maximum file size in bytes for ELF files. Default value of 0 means all files will "
37+ " be parsed regardless of size." );
38+
3539namespace px {
3640namespace stirling {
3741namespace obj_tools {
@@ -46,6 +50,41 @@ struct LowercaseHex {
4650};
4751} // namespace
4852
53+ StatusOr<std::unique_ptr<ElfReader>> ElfReader::CreateImpl (
54+ const std::string& binary_path, const std::filesystem::path& debug_file_dir) {
55+ VLOG (1 ) << absl::Substitute (" Creating ElfReader, [binary=$0] [debug_file_dir=$1]" , binary_path,
56+ debug_file_dir.string ());
57+
58+ auto elf_reader = std::unique_ptr<ElfReader>(new ElfReader);
59+ elf_reader->binary_path_ = binary_path;
60+
61+ if (!elf_reader->elf_reader_ .load_header_and_sections (binary_path)) {
62+ return error::Internal (" Can't find or process ELF file $0" , binary_path);
63+ }
64+
65+ // Check for external debug symbols.
66+ Status s = elf_reader->LocateDebugSymbols (debug_file_dir);
67+ if (s.ok ()) {
68+ std::string debug_symbols_path = elf_reader->debug_symbols_path_ .string ();
69+
70+ bool internal_debug_symbols =
71+ fs::Equivalent (elf_reader->debug_symbols_path_ , binary_path).ConsumeValueOr (true );
72+
73+ // If external debug symbols were found, load that ELF info instead.
74+ if (!internal_debug_symbols) {
75+ std::string debug_symbols_path = elf_reader->debug_symbols_path_ .string ();
76+ LOG (INFO) << absl::Substitute (" Found debug symbols file $0 for binary $1" , debug_symbols_path,
77+ binary_path);
78+ elf_reader->elf_reader_ .load_header_and_sections (debug_symbols_path);
79+ return elf_reader;
80+ }
81+ }
82+
83+ // Debug symbols were either in the binary, or no debug symbols were found,
84+ // so return original elf_reader.
85+ return elf_reader;
86+ }
87+
4988Status ElfReader::LocateDebugSymbols (const std::filesystem::path& debug_file_dir) {
5089 std::string build_id;
5190 std::string debug_link;
@@ -158,40 +197,26 @@ Status ElfReader::LocateDebugSymbols(const std::filesystem::path& debug_file_dir
158197 return error::Internal (" Could not find debug symbols for $0" , binary_path_);
159198}
160199
161- // TODO(oazizi): Consider changing binary_path to std::filesystem::path.
162200StatusOr<std::unique_ptr<ElfReader>> ElfReader::Create (
163201 const std::string& binary_path, const std::filesystem::path& debug_file_dir) {
164- VLOG (1 ) << absl::Substitute (" Creating ElfReader, [binary=$0] [debug_file_dir=$1]" , binary_path,
165- debug_file_dir.string ());
166- auto elf_reader = std::unique_ptr<ElfReader>(new ElfReader);
167-
168- elf_reader->binary_path_ = binary_path;
169-
170- if (!elf_reader->elf_reader_ .load_header_and_sections (binary_path)) {
171- return error::Internal (" Can't find or process ELF file $0" , binary_path);
172- }
173-
174- // Check for external debug symbols.
175- Status s = elf_reader->LocateDebugSymbols (debug_file_dir);
176- if (s.ok ()) {
177- std::string debug_symbols_path = elf_reader->debug_symbols_path_ .string ();
178-
179- bool internal_debug_symbols =
180- fs::Equivalent (elf_reader->debug_symbols_path_ , binary_path).ConsumeValueOr (true );
181-
182- // If external debug symbols were found, load that ELF info instead.
183- if (!internal_debug_symbols) {
184- std::string debug_symbols_path = elf_reader->debug_symbols_path_ .string ();
185- LOG (INFO) << absl::Substitute (" Found debug symbols file $0 for binary $1" , debug_symbols_path,
186- binary_path);
187- elf_reader->elf_reader_ .load_header_and_sections (debug_symbols_path);
188- return elf_reader;
202+ if (FLAGS_elf_reader_max_file_size != 0 ) {
203+ PX_ASSIGN_OR_RETURN (const auto stat, fs::Stat (binary_path));
204+ int64_t file_size = stat.st_size ;
205+ if (file_size > FLAGS_elf_reader_max_file_size) {
206+ return error::Internal (
207+ " File size $0 exceeds ElfReader's max file size $1. Refusing to process file" , file_size,
208+ FLAGS_elf_reader_max_file_size);
209+ } else if (file_size < 0 ) {
210+ return error::Internal (" stat() returned negative file size $0 for file $1" , file_size,
211+ binary_path);
189212 }
190213 }
214+ return CreateImpl (binary_path, debug_file_dir);
215+ }
191216
192- // Debug symbols were either in the binary, or no debug symbols were found,
193- // so return original elf_reader.
194- return elf_reader ;
217+ StatusOr<std::unique_ptr<ElfReader>> ElfReader::CreateUncapped (
218+ const std::string& binary_path, const std::filesystem::path& debug_file_dir) {
219+ return CreateImpl (binary_path, debug_file_dir) ;
195220}
196221
197222StatusOr<ELFIO::section*> ElfReader::SymtabSection () {
0 commit comments