Fix wrong MemoryImage address given to the elf interpreter

This commit is contained in:
Alex 2023-03-20 05:17:35 +02:00
parent 6492da3237
commit 45cd4bb13c
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
5 changed files with 39 additions and 30 deletions

View File

@ -26,7 +26,7 @@ namespace Execute
{ {
char Path[256]; char Path[256];
void *MemoryImage; void *MemoryImage;
struct InterpreterIPCDataLibrary Libraries[256]; struct InterpreterIPCDataLibrary Libraries[64];
} InterpreterIPCData; } InterpreterIPCData;
/* Passing arguments as a sanity check and debugging. */ /* Passing arguments as a sanity check and debugging. */
@ -42,7 +42,7 @@ namespace Execute
Handle = Process->IPC->SearchByToken(UniqueToken); Handle = Process->IPC->SearchByToken(UniqueToken);
if (Handle == nullptr) if (Handle == nullptr)
debug("Failed"); debug("Failed");
TaskManager->Sleep(100); TaskManager->Sleep(200);
if (Handle == nullptr) if (Handle == nullptr)
debug("Retrying..."); debug("Retrying...");
} }
@ -56,6 +56,16 @@ namespace Execute
{ {
strcpy(TmpBuffer->Libraries[i].Name, NeededLibraries[i].c_str()); strcpy(TmpBuffer->Libraries[i].Name, NeededLibraries[i].c_str());
} }
#ifdef DEBUG
debug("Path: %s", TmpBuffer->Path);
debug("MemoryImage: %p", TmpBuffer->MemoryImage);
for (size_t i = 0; i < NeededLibraries.size(); i++)
{
debug("Library: %s", TmpBuffer->Libraries[i].Name);
}
#endif
int NotFoundRetry = 0; int NotFoundRetry = 0;
RetryIPCWrite: RetryIPCWrite:
InterProcessCommunication::IPCErrorCode ret = Process->IPC->Write(Handle->ID, TmpBuffer, sizeof(InterpreterIPCData)); InterProcessCommunication::IPCErrorCode ret = Process->IPC->Write(Handle->ID, TmpBuffer, sizeof(InterpreterIPCData));
@ -66,16 +76,6 @@ namespace Execute
TaskManager->Sleep(100); TaskManager->Sleep(100);
goto RetryIPCWrite; goto RetryIPCWrite;
} }
else if (ret == InterProcessCommunication::IPCErrorCode::IPCIDNotFound)
{
if (NotFoundRetry < 100)
{
debug("IPC not found, retrying...");
TaskManager->Sleep(1000);
NotFoundRetry++;
goto RetryIPCWrite;
}
}
delete TmpBuffer; delete TmpBuffer;
CPU::Halt(true); CPU::Halt(true);
} }
@ -216,7 +216,7 @@ namespace Execute
{ {
InterpreterTargetProcess = Process; InterpreterTargetProcess = Process;
InterpreterTargetPath = new String(Path); /* We store in a String because Path may get changed while outside ELFLoad(). */ InterpreterTargetPath = new String(Path); /* We store in a String because Path may get changed while outside ELFLoad(). */
InterpreterMemoryImage = bl.MemoryImage; InterpreterMemoryImage = bl.VirtualMemoryImage;
InterpreterNeededLibraries = bl.NeededLibraries; InterpreterNeededLibraries = bl.NeededLibraries;
__sync; __sync;
TCB *InterpreterIPCThread = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (IP)ELFInterpreterThreadWrapper); TCB *InterpreterIPCThread = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (IP)ELFInterpreterThreadWrapper);

View File

@ -29,6 +29,7 @@ namespace Execute
uintptr_t BaseAddress = UINTPTR_MAX; uintptr_t BaseAddress = UINTPTR_MAX;
uint64_t ElfAppSize = 0; uint64_t ElfAppSize = 0;
uintptr_t EntryPoint = ELFHeader->e_entry; uintptr_t EntryPoint = ELFHeader->e_entry;
debug("%s's entry point is %#lx", ExFile->Name, EntryPoint);
Elf64_Phdr ItrPhdr; Elf64_Phdr ItrPhdr;
@ -58,7 +59,7 @@ namespace Execute
/* If required, MemoryImage will be at virtual address. (unless has PIE) /* If required, MemoryImage will be at virtual address. (unless has PIE)
* *
* tl;dr this is where the code is stored. */ * tl;dr this is where the code is stored. */
void *MemoryImage = ELFCreateMemoryImage(ELFBase.TmpMem, pV, ElfFile, ElfAppSize); MmImage MemoryImage = ELFCreateMemoryImage(ELFBase.TmpMem, pV, ElfFile, ElfAppSize);
debug("Solving symbols for address: %#llx", (uintptr_t)ElfFile); debug("Solving symbols for address: %#llx", (uintptr_t)ElfFile);
Elf64_Shdr *ElfSections = (Elf64_Shdr *)((uintptr_t)ElfFile + ELFHeader->e_shoff); Elf64_Shdr *ElfSections = (Elf64_Shdr *)((uintptr_t)ElfFile + ELFHeader->e_shoff);
@ -87,7 +88,7 @@ namespace Execute
/* Calculate entry point */ /* Calculate entry point */
memcpy(&ItrPhdr, (uint8_t *)ElfFile + ELFHeader->e_phoff, sizeof(Elf64_Phdr)); memcpy(&ItrPhdr, (uint8_t *)ElfFile + ELFHeader->e_phoff, sizeof(Elf64_Phdr));
if (ItrPhdr.p_vaddr == 0) if (ItrPhdr.p_vaddr == 0)
EntryPoint += (uintptr_t)MemoryImage; EntryPoint += (uintptr_t)MemoryImage.Virtual;
char InterpreterPath[256]; char InterpreterPath[256];
@ -107,7 +108,7 @@ namespace Execute
debug("PT_LOAD - Offset: %#lx, VirtAddr: %#lx, FileSiz: %ld, MemSiz: %ld, Align: %#lx", debug("PT_LOAD - Offset: %#lx, VirtAddr: %#lx, FileSiz: %ld, MemSiz: %ld, Align: %#lx",
ItrPhdr.p_offset, ItrPhdr.p_vaddr, ItrPhdr.p_offset, ItrPhdr.p_vaddr,
ItrPhdr.p_filesz, ItrPhdr.p_memsz, ItrPhdr.p_align); ItrPhdr.p_filesz, ItrPhdr.p_memsz, ItrPhdr.p_align);
uintptr_t MAddr = (ItrPhdr.p_vaddr - BaseAddress) + (uintptr_t)MemoryImage; uintptr_t MAddr = (ItrPhdr.p_vaddr - BaseAddress) + (uintptr_t)MemoryImage.Phyiscal;
fixme("Address: %#lx %s%s%s", MAddr, fixme("Address: %#lx %s%s%s", MAddr,
(ItrPhdr.p_flags & PF_R) ? "R" : "", (ItrPhdr.p_flags & PF_R) ? "R" : "",
(ItrPhdr.p_flags & PF_W) ? "W" : "", (ItrPhdr.p_flags & PF_W) ? "W" : "",
@ -191,14 +192,15 @@ namespace Execute
ELFBase.auxv.push_back({.archaux = {.a_type = AT_EXECFN, .a_un = {.a_val = (uint64_t)vfs->GetPathFromNode(ExFile->node).Get()}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_EXECFN, .a_un = {.a_val = (uint64_t)vfs->GetPathFromNode(ExFile->node).Get()}}});
ELFBase.auxv.push_back({.archaux = {.a_type = AT_PLATFORM, .a_un = {.a_val = (uint64_t)aux_platform}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_PLATFORM, .a_un = {.a_val = (uint64_t)aux_platform}}});
ELFBase.auxv.push_back({.archaux = {.a_type = AT_ENTRY, .a_un = {.a_val = (uint64_t)EntryPoint}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_ENTRY, .a_un = {.a_val = (uint64_t)EntryPoint}}});
ELFBase.auxv.push_back({.archaux = {.a_type = AT_BASE, .a_un = {.a_val = (uint64_t)MemoryImage}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_BASE, .a_un = {.a_val = (uint64_t)MemoryImage.Virtual}}});
ELFBase.auxv.push_back({.archaux = {.a_type = AT_PAGESZ, .a_un = {.a_val = (uint64_t)PAGE_SIZE}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_PAGESZ, .a_un = {.a_val = (uint64_t)PAGE_SIZE}}});
ELFBase.auxv.push_back({.archaux = {.a_type = AT_PHNUM, .a_un = {.a_val = (uint64_t)ELFHeader->e_phnum}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_PHNUM, .a_un = {.a_val = (uint64_t)ELFHeader->e_phnum}}});
ELFBase.auxv.push_back({.archaux = {.a_type = AT_PHENT, .a_un = {.a_val = (uint64_t)ELFHeader->e_phentsize}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_PHENT, .a_un = {.a_val = (uint64_t)ELFHeader->e_phentsize}}});
ELFBase.auxv.push_back({.archaux = {.a_type = AT_PHDR, .a_un = {.a_val = (uint64_t)ELFHeader->e_phoff}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_PHDR, .a_un = {.a_val = (uint64_t)ELFHeader->e_phoff}}});
ELFBase.InstructionPointer = EntryPoint; ELFBase.InstructionPointer = EntryPoint;
ELFBase.MemoryImage = MemoryImage; ELFBase.MemoryImage = MemoryImage.Phyiscal;
ELFBase.VirtualMemoryImage = MemoryImage.Virtual;
ELFBase.Success = true; ELFBase.Success = true;
return ELFBase; return ELFBase;

View File

@ -140,7 +140,7 @@ namespace Execute
return nullptr; return nullptr;
} }
void *ELFCreateMemoryImage(Memory::MemMgr *mem, Memory::Virtual &pV, void *ElfFile, size_t Length) MmImage ELFCreateMemoryImage(Memory::MemMgr *mem, Memory::Virtual &pV, void *ElfFile, size_t Length)
{ {
void *MemoryImage = nullptr; void *MemoryImage = nullptr;
Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)ElfFile; Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)ElfFile;
@ -153,7 +153,7 @@ namespace Execute
fixme("Text relocation is not(?) tested yet!"); fixme("Text relocation is not(?) tested yet!");
MemoryImage = (uint8_t *)mem->RequestPages(TO_PAGES(Length), true); MemoryImage = (uint8_t *)mem->RequestPages(TO_PAGES(Length), true);
memset(MemoryImage, 0, Length); memset(MemoryImage, 0, Length);
return MemoryImage; return {MemoryImage, 0x0};
} }
Elf64_Phdr ItrPhdr; Elf64_Phdr ItrPhdr;
@ -177,7 +177,7 @@ namespace Execute
debug("p_vaddr is 0, allocating %ld pages for image", TO_PAGES(Length)); debug("p_vaddr is 0, allocating %ld pages for image", TO_PAGES(Length));
MemoryImage = mem->RequestPages(TO_PAGES(Length), true); MemoryImage = mem->RequestPages(TO_PAGES(Length), true);
memset(MemoryImage, 0, Length); memset(MemoryImage, 0, Length);
return MemoryImage; return {MemoryImage, (void *)FirstProgramHeaderVirtualAddress};
} }
} }
@ -195,7 +195,7 @@ namespace Execute
pV.Remap((void *)((uintptr_t)FirstProgramHeaderVirtualAddress + (i * PAGE_SIZE)), (void *)((uintptr_t)MemoryImage + (i * PAGE_SIZE)), Memory::PTFlag::RW | Memory::PTFlag::US); pV.Remap((void *)((uintptr_t)FirstProgramHeaderVirtualAddress + (i * PAGE_SIZE)), (void *)((uintptr_t)MemoryImage + (i * PAGE_SIZE)), Memory::PTFlag::RW | Memory::PTFlag::US);
debug("Remapped: %#lx -> %#lx", (uintptr_t)FirstProgramHeaderVirtualAddress + (i * PAGE_SIZE), (uintptr_t)MemoryImage + (i * PAGE_SIZE)); debug("Remapped: %#lx -> %#lx", (uintptr_t)FirstProgramHeaderVirtualAddress + (i * PAGE_SIZE), (uintptr_t)MemoryImage + (i * PAGE_SIZE));
} }
return MemoryImage; return {MemoryImage, (void *)FirstProgramHeaderVirtualAddress};
} }
uintptr_t LoadELFInterpreter(Memory::MemMgr *mem, Memory::Virtual &pV, const char *Interpreter) uintptr_t LoadELFInterpreter(Memory::MemMgr *mem, Memory::Virtual &pV, const char *Interpreter)
@ -252,7 +252,7 @@ namespace Execute
ElfAppSize = MAX(ElfAppSize, SegmentEnd); ElfAppSize = MAX(ElfAppSize, SegmentEnd);
} }
void *MemoryImage = ELFCreateMemoryImage(mem, pV, (void *)File->node->Address, ElfAppSize); MmImage MemoryImage = ELFCreateMemoryImage(mem, pV, (void *)File->node->Address, ElfAppSize);
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++) for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
{ {
@ -265,7 +265,7 @@ namespace Execute
debug("PT_LOAD - Offset: %#lx, VirtAddr: %#lx, FileSiz: %ld, MemSiz: %ld, Align: %#lx", debug("PT_LOAD - Offset: %#lx, VirtAddr: %#lx, FileSiz: %ld, MemSiz: %ld, Align: %#lx",
ItrPhdr.p_offset, ItrPhdr.p_vaddr, ItrPhdr.p_offset, ItrPhdr.p_vaddr,
ItrPhdr.p_filesz, ItrPhdr.p_memsz, ItrPhdr.p_align); ItrPhdr.p_filesz, ItrPhdr.p_memsz, ItrPhdr.p_align);
uintptr_t MAddr = (ItrPhdr.p_vaddr - BaseAddress) + (uintptr_t)MemoryImage; uintptr_t MAddr = (ItrPhdr.p_vaddr - BaseAddress) + (uintptr_t)MemoryImage.Phyiscal;
fixme("Address: %#lx %s%s%s", MAddr, fixme("Address: %#lx %s%s%s", MAddr,
(ItrPhdr.p_flags & PF_R) ? "R" : "", (ItrPhdr.p_flags & PF_R) ? "R" : "",
(ItrPhdr.p_flags & PF_W) ? "W" : "", (ItrPhdr.p_flags & PF_W) ? "W" : "",
@ -277,8 +277,8 @@ namespace Execute
} }
vfs->Close(File); vfs->Close(File);
debug("Interpreter entry point: %#lx (%#lx + %#lx)", (uintptr_t)MemoryImage + ELFHeader->e_entry, debug("Interpreter entry point: %#lx (%#lx + %#lx)", (uintptr_t)MemoryImage.Phyiscal + ELFHeader->e_entry,
(uintptr_t)MemoryImage, ELFHeader->e_entry); (uintptr_t)MemoryImage.Phyiscal, ELFHeader->e_entry);
return (uintptr_t)MemoryImage + ELFHeader->e_entry; return (uintptr_t)MemoryImage.Phyiscal + ELFHeader->e_entry;
} }
} }

View File

@ -66,7 +66,7 @@ namespace Execute
memcpy(LibFile, (void *)ElfImage, Length); memcpy(LibFile, (void *)ElfImage, Length);
Memory::Virtual ncpV = pV; Memory::Virtual ncpV = pV;
sl.MemoryImage = ELFCreateMemoryImage(mem, ncpV, LibFile, Length); sl.MemoryImage = ELFCreateMemoryImage(mem, ncpV, LibFile, Length).Phyiscal;
{ {
uintptr_t BaseAddress = UINTPTR_MAX; uintptr_t BaseAddress = UINTPTR_MAX;

View File

@ -62,6 +62,7 @@ namespace Execute
Vector<String> NeededLibraries; Vector<String> NeededLibraries;
void *MemoryImage; void *MemoryImage;
void *VirtualMemoryImage;
/* This should be deleted after copying the allocated pages to the thread /* This should be deleted after copying the allocated pages to the thread
Intended to be used only inside BaseLoad.cpp */ Intended to be used only inside BaseLoad.cpp */
@ -71,6 +72,12 @@ namespace Execute
Vector<AuxiliaryVector> auxv; Vector<AuxiliaryVector> auxv;
}; };
struct MmImage
{
void *Phyiscal;
void *Virtual;
};
BinaryType GetBinaryType(void *Image); BinaryType GetBinaryType(void *Image);
BinaryType GetBinaryType(char *Path); BinaryType GetBinaryType(char *Path);
@ -94,9 +101,9 @@ namespace Execute
* @param pV Memory::Virtual object to use * @param pV Memory::Virtual object to use
* @param ElfFile ELF file loaded in memory (FULL FILE) * @param ElfFile ELF file loaded in memory (FULL FILE)
* @param Length Length of @p ElfFile * @param Length Length of @p ElfFile
* @return void* The Memory Image * @return The Memory Image (Physical and Virtual)
*/ */
void *ELFCreateMemoryImage(Memory::MemMgr *mem, Memory::Virtual &pV, void *ElfFile, size_t Length); MmImage ELFCreateMemoryImage(Memory::MemMgr *mem, Memory::Virtual &pV, void *ElfFile, size_t Length);
uintptr_t LoadELFInterpreter(Memory::MemMgr *mem, Memory::Virtual &pV, const char *Interpreter); uintptr_t LoadELFInterpreter(Memory::MemMgr *mem, Memory::Virtual &pV, const char *Interpreter);