You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Some ELF executable (see regular Golang one) are constructed such that PT_NOTE segment comes before PT_LOAD as you see below per readelf:
Elf file type is EXEC (Executable file)
Entry point 0x44f2a0
There are 7 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x0000000000000188 0x0000000000000188 R 0x1000
NOTE 0x0000000000000f9c 0x0000000000400f9c 0x0000000000400f9c
0x0000000000000064 0x0000000000000064 R 0x4
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x00000000000821d5 0x00000000000821d5 R E 0x1000
LOAD 0x0000000000083000 0x0000000000483000 0x0000000000483000
0x00000000000905dd 0x00000000000905dd R 0x1000
LOAD 0x0000000000114000 0x0000000000514000 0x0000000000514000
0x00000000000136c0 0x00000000000323f8 RW 0x1000
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x8
LOOS+0x5041580 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 0x8
OSv linker (see object::load_segments()) processes segments in the order as they come. And when PT_NOTE segment comes before PT_LOAD we get page fault in the ELF note constructor looking like this:
Possibly the right fix would either require delaying processing PT_NOTE after all PT_LOAD segments are processed or making all PT_LOAD processed first which all boils down to the similar type of a solution.
The text was updated successfully, but these errors were encountered:
Good catch.
The smallest patch is probably to move the PT_NOTE handling to a separate loop right after the loop it's now in (with a comment saying it needs to be after the LOAD).
But perhaps a "cleaner" solution is to change load_segments() to do only what it's name says - call load_segment() on the segments listed as PT_LOAD. Just like unload_segments() only unloads these segments and does nothing else. We could then have a separate function to look for PT_TLS and set the TLS variables, or to look for the dynamic table, or check if there is a PT_INTERP, and a separate function to read notes (maybe not each of these needs to be a separate function, but it can be), and we can call these in the order we want. We already have other speciaized functions that only look for specific headers: e.g., fix_permissions() only looks for PT_GNU_RELRO headers. make_text_writeable() only looks for PT_LOAD,
Some ELF executable (see regular Golang one) are constructed such that PT_NOTE segment comes before PT_LOAD as you see below per readelf:
OSv linker (see object::load_segments()) processes segments in the order as they come. And when PT_NOTE segment comes before PT_LOAD we get page fault in the ELF note constructor looking like this:
Possibly the right fix would either require delaying processing PT_NOTE after all PT_LOAD segments are processed or making all PT_LOAD processed first which all boils down to the similar type of a solution.
The text was updated successfully, but these errors were encountered: