swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.49k stars 10.35k forks source link

[SR-12893] When vaddr and offset overlap, ObjectMemoryReader can read garbage #55339

Open swift-ci opened 4 years ago

swift-ci commented 4 years ago
Previous ID SR-12893
Radar None
Original Reporter 3405691582 (JIRA User)
Type Bug
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: 333589a8f959aa825e953c912e67a22a

Issue Description:

swift-reflection-dump is used by various Reflection unit tests (e.g. Reflection/capture_descriptors.sil and Reflection/typeref_decoding_imported.swift), broadly speaking, generating shared objects and then running the tool over it.

swift-reflection-dump uses an ObjectMemoryReader which takes some executable images and requests for vaddrs and reads from those images. For ELF binaries, Image::scanELFType looks at the program headers, reads segments, and saves them indexed by the program header vaddr. When the ObjectMemoryReader wants to read a given number of bytes from a given vaddr, the relevant segment is accessed by iterating through the stored segments looking whether the specified address and byte range lies inside a segment (see Image::getContentsAtAddress)).

However, ReflectionContext::readELFSections needs to read the section headers. The section table is never loaded and so is not part of a loaded segment. Therefore, Image::scanELF installs a catch-all pseudo-segment which contains the entire executable image.

ReflectionContext reads ELF sections by looking for e_shoff and then subsequent sections by e_shoff + i * e_shentsize. But this is done via the ObjectMemoryReader which wants vaddrs. When the requested offset is not part of a segment, we fall through to the catch-all case and everything is OK, but if the offset when interpreted as a vaddr matches an already-existing segment, we can read garbage as an ELF header, swift-reflection-dump segfaults, and the unit test crashes.

swift-ci commented 4 years ago

Comment by 3405691582 (JIRA)

cc @jckarter