-
Notifications
You must be signed in to change notification settings - Fork 15k
[ELF]Add overflow check to ELF note iterator #160451
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Signed-off-by: Ruoyu Qiu <cabbaken@outlook.com>
|
@llvm/pr-subscribers-llvm-binary-utilities Author: Ruoyu Qiu (cabbaken) ChangesAdd overflow check to ELF note iterator to handle large Full diff: https://github.com/llvm/llvm-project/pull/160451.diff 1 Files Affected:
diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h
index 0b362d389c177..59f63eb6b5bb6 100644
--- a/llvm/include/llvm/Object/ELF.h
+++ b/llvm/include/llvm/Object/ELF.h
@@ -407,7 +407,8 @@ class ELFFile {
Elf_Note_Iterator notes_begin(const Elf_Phdr &Phdr, Error &Err) const {
assert(Phdr.p_type == ELF::PT_NOTE && "Phdr is not of type PT_NOTE");
ErrorAsOutParameter ErrAsOutParam(Err);
- if (Phdr.p_offset + Phdr.p_filesz > getBufSize()) {
+ if (Phdr.p_offset + Phdr.p_filesz > getBufSize() ||
+ Phdr.p_offset + Phdr.p_filesz < Phdr.p_offset) {
Err =
createError("invalid offset (0x" + Twine::utohexstr(Phdr.p_offset) +
") or size (0x" + Twine::utohexstr(Phdr.p_filesz) + ")");
@@ -435,7 +436,8 @@ class ELFFile {
Elf_Note_Iterator notes_begin(const Elf_Shdr &Shdr, Error &Err) const {
assert(Shdr.sh_type == ELF::SHT_NOTE && "Shdr is not of type SHT_NOTE");
ErrorAsOutParameter ErrAsOutParam(Err);
- if (Shdr.sh_offset + Shdr.sh_size > getBufSize()) {
+ if (Shdr.sh_offset + Shdr.sh_size > getBufSize() ||
+ Shdr.sh_offset + Shdr.sh_size < Shdr.sh_offset) {
Err =
createError("invalid offset (0x" + Twine::utohexstr(Shdr.sh_offset) +
") or size (0x" + Twine::utohexstr(Shdr.sh_size) + ")");
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test case? You should be able to craft an input using yaml2obj either in a lit or unit test that exercises these two code paths.
The PR description should mention both the size and offset fields, not just the size fields.
|
Will it be good to add a unit test in |
ELFObjectFileTest.cpp is for testing the ELFObjectFile.cpp file. There's ELFTest.cpp for testing ELF.h/ELF.cpp, so you should add it to that one. |
Signed-off-by: Ruoyu Qiu <cabbaken@outlook.com>
Signed-off-by: Ruoyu Qiu <cabbaken@outlook.com>
Signed-off-by: Ruoyu Qiu <cabbaken@outlook.com>
I've added the unit test in ELFTest.cpp. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One nit, otherwise looks fine.
llvm/unittests/Object/ELFTest.cpp
Outdated
| .str()); | ||
| }; | ||
|
|
||
| auto PhdrsOrErr = Obj.program_headers(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd avoid auto in these tests to make it clearer what the type is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type of PhdrsOrErr is Expected<ELFFile<ELF64LE>::Elf_Phdr_Range>, which is a bit verbose here. Since the getBuildID code uses auto, I followed the same style.
I can adjust this if needed.
llvm/unittests/Object/ELFTest.cpp
Outdated
| auto PhdrsOrErr = Obj.program_headers(); | ||
| Expected<ELFFile<ELF64LE>::Elf_Phdr_Range> PhdrsOrErr = Obj.program_headers(); | ||
| EXPECT_FALSE(!PhdrsOrErr); | ||
| for (auto P : *PhdrsOrErr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still using auto here and in the similar loop below. You could probably add a couple of using declarations to avoid repeating the full ELFFile<ELF64LE>::Elf_Phdr_Range and Shdr equivalent.
Signed-off-by: Ruoyu Qiu <cabbaken@outlook.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One remaining nit, otherwise LGTM.
llvm/unittests/Object/ELFTest.cpp
Outdated
| FileSize: 0xffffffffffffff88 | ||
| FirstSec: .note.gnu.build-id | ||
| LastSec: .note.gnu.build-id | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: delete this blank line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
Signed-off-by: Ruoyu Qiu <cabbaken@outlook.com>
|
@cabbaken, do you need me to merge this? |
|
That would be great, thanks. I don’t have merge rights here. |
Add overflow check to ELF note iterator to handle large `p_filesz` or `sh_size`, avoid accessing invalid memory. --------- Signed-off-by: Ruoyu Qiu <cabbaken@outlook.com>
Add overflow check to ELF note iterator to handle large
p_fileszorsh_size, avoid accessing invalid memory.