-
Notifications
You must be signed in to change notification settings - Fork 159
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
read_ref: allow zero size reads at any offset #758
Conversation
This seems to happen whenever I'm not opposed to this fix, especially since it matches It's decision between whether this crate is only meant to handle valid files, or whether it should do best effort parsing for any file, no matter how corrupt, or whether it should be something in between. |
Created by running ``` cd elf objcopy --only-keep-debug base debug-only ``` To be used to add a test for gimli-rs/object#758
Made a PR for adding the file gimli-rs/object-testfiles#21. Will update the submodule and add a test once that PR is merged.
I'm not sure either.
Yes, this would work as well, and I can do that if you want me to.
Yeah, and it also depends on how defines "valid". Is an offset that is out of bounds but never read from (because size is zero) invalid? I'm happy with any decision, we can also just change this in |
Created by running ``` cd elf objcopy --only-keep-debug base debug-only ``` To be used to add a test for gimli-rs/object#758
I'm fine with it being fixed in |
Some ELF files do have segments with size zero, at offsets that are invalid / out of bounds. This commit changes the default `ReadRef` implementation for `&[u8]` to permit reads that are out of bounds, if the requested length is zero, by returning `&[]`. Examples of such files are many ARM ELF files in e.g. debian repositories, for example `/usr/lib/debug/.build-id/bd/dd2eaf3326ffce6d173666b5f3e62a376e123a.debug` in package `libgedit-gfls-1-0-dbgsym_0.2.1-2_arm64.deb`: ``` ~ cp /usr/lib/debug/.build-id/bd/dd2eaf3326ffce6d173666b5f3e62a376e123a.debug /tmp/bad_file.elf ~ r2 /tmp/bad_file.elf [0x0000027c]> iI~binsz binsz 64184 [0x0000027c]> iSS [Segments] nth paddr size vaddr vsize perm type name ――――――――――――――――――――――――――――――――――――――――――――――――――――――― 0 0x00000000 0x27c 0x00000000 0x55e0 -r-x MAP LOAD0 1 0x0000fab8 0x0 0x0001fab8 0x5c0 -rw- MAP LOAD1 2 0x0000fab8 0x0 0x0001fb28 0x240 -rw- MAP DYNAMIC [...] 8 0x0000fab8 0x0 0x0001fab8 0x548 -r-- MAP GNU_RELRO ``` This file has multiple segments starting at `0xfab8` (the end of the file), with a physical size of `0`, while the file size is also `0xfab8` (64184). The current `ReadRef` implementation for `&[u8]` causes `ProgramHeader::data` to fail for them, causing e.g. `ElfSegment::bytes` to also fail. While a caller could handle this error, or one could provide their own type implementing `ReadRef` this way, I think it makes sense to do this by default, since no data is *actually* being read out of bounds, but with the current implementation we still try to index out of bounds and then error. Notably with this change this also matches the implementation of `ReadRef` for `ReadCache` which already has a similar check implemented for `read_bytes_at`.
Done, added a unit test |
Hi, this PR changes the implementation of
read_bytes_at
inReadRef
for&[u8]
to allow zero size reads for any offset, even if that offset is out of bounds.This makes it match the behavior of
ReadRef
forReadCache
, and also makes e.g.ElfSegment::bytes
work for zero sized segments as seen in real world ELF files.Please let me know if you have any comments or would like me to change something, or if you want to keep the current behavior, I'm also happy to just carry this patch in a fork, or to add this behavior in a custom
ReadRef
implementation only, if there is some reason for disallowing zero sized reads that are out of bounds.Commit message copied below with more detail:
Some ELF files do have segments with size zero, at offsets that are invalid / out of bounds. This commit changes the default
ReadRef
implementation for&[u8]
to permit reads that are out of bounds, if the requested length is zero, by returning&[]
.Examples of such files are many ARM ELF files in e.g. debian repositories, for example
/usr/lib/debug/.build-id/bd/dd2eaf3326ffce6d173666b5f3e62a376e123a.debug
in packagelibgedit-gfls-1-0-dbgsym_0.2.1-2_arm64.deb
:This file has multiple segments starting at
0xfab8
(the end of the file), with a physical size of0
, while the file size is also0xfab8
(64184).The current
ReadRef
implementation for&[u8]
causesProgramHeader::data
to fail for them, causing e.g.ElfSegment::bytes
to also fail.While a caller could handle this error, or one could provide their own type implementing
ReadRef
this way, I think it makes sense to do this by default, since no data is actually being read out of bounds, but with the current implementation we still try to index out of bounds and then error.Notably with this change this also matches the implementation of
ReadRef
forReadCache
which already has a similar check implemented forread_bytes_at
.