[PATCH] D86422: [ELF] .note.gnu.property: error for invalid pr_datasize
George Rimar via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 24 02:55:03 PDT 2020
grimar added inline comments.
================
Comment at: lld/ELF/InputFiles.cpp:795
// Read one NOTE record.
- if (data.size() < sizeof(Elf_Nhdr))
- fatal(toString(obj) + ": .note.gnu.property: section too short");
-
auto *nhdr = reinterpret_cast<const Elf_Nhdr *>(data.data());
+ if (data.size() < sizeof(Elf_Nhdr) || data.size() < nhdr->getSize())
----------------
psmith wrote:
> Will this work if the Host is little endian and the data in big-endian format?
I believe yes. `ELF_Nhdr` is `Elf_Nhdr_Impl`:
```
template <class ELFT>
struct Elf_Nhdr_Impl {
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
Elf_Word n_namesz;
Elf_Word n_descsz;
Elf_Word n_type;
...
```
And `Elf_Word `s here are `using Word = packed<uint32_t>` which respects
endianess:
```
struct packed_endian_specific_integral {
...
operator value_type() const {
return endian::read<value_type, endian, alignment>(Ptr);
}
```
```
template <typename value_type, std::size_t alignment>
inline value_type read(const void *memory, endianness endian) {
value_type ret;
memcpy(&ret,
LLVM_ASSUME_ALIGNED(
memory, (detail::PickAlignment<value_type, alignment>::value)),
sizeof(value_type));
return byte_swap<value_type>(ret, endian);
}
```
```
template <typename value_type>
inline value_type byte_swap(value_type value, endianness endian) {
if ((endian != native) && (endian != system_endianness()))
sys::swapByteOrder(value);
return value;
}
```
================
Comment at: lld/ELF/InputFiles.cpp:818
+ if (desc.size() < 8 + size)
+ reportFatal(desc, "program property is too short");
----------------
2 points:
1) You should be able to use `read32` from `Target.h`:
```
inline uint32_t read32(const void *p) {
return llvm::support::endian::read32(p, config->endianness);
}
```
2) It probably would read slightly better if it was:
```
if (desc.size() < 8)
reportFatal(...);
uint32_t type = read32(desc.data());
uint32_t size = read32(desc.data() + 4);
desc = desc.drop_front(8);
if (desc.size() < size)
reportFatal(desc, "program property is too short");
```
i.e
a) I'd not start reading the `size` + `type` when the data is truncated (just like the code on the left).
b) Early dropping of 8 bytes at start should allow to avoid the need of `+ 8` in the code below.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D86422/new/
https://reviews.llvm.org/D86422
More information about the llvm-commits
mailing list