Changeset 92063 in vbox for trunk/src/VBox/Frontends/VBoxHeadless
- Timestamp:
- Oct 26, 2021 7:41:11 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp
r92060 r92063 484 484 } 485 485 #endif /* VBOX_WITH_RECORDING defined */ 486 487 /* This should be done in the hardening code already and it fails on Monterey. */488 #if 0 //def RT_OS_DARWIN489 490 # include <unistd.h>491 # include <stdio.h>492 # include <dlfcn.h>493 # include <iprt/formats/mach-o.h>494 495 /**496 * Override this one to try hide the fact that we're setuid to root497 * orginially.498 */499 int issetugid_for_AppKit(void)500 {501 Dl_info Info = {0};502 char szMsg[512];503 size_t cchMsg;504 const void * uCaller = __builtin_return_address(0);505 if (dladdr(uCaller, &Info))506 cchMsg = snprintf(szMsg, sizeof(szMsg), "DEBUG: issetugid_for_AppKit was called by %p %s::%s+%p\n",507 uCaller, Info.dli_fname, Info.dli_sname, (void *)((uintptr_t)uCaller - (uintptr_t)Info.dli_saddr));508 else509 cchMsg = snprintf(szMsg, sizeof(szMsg), "DEBUG: issetugid_for_AppKit was called by %p\n", uCaller);510 write(2, szMsg, cchMsg);511 return 0;512 }513 514 static bool patchExtSym(mach_header_64_t *pHdr, const char *pszSymbol, uintptr_t uNewValue)515 {516 /*517 * First do some basic header checks and the scan the load518 * commands for the symbol table info.519 */520 AssertLogRelMsgReturn(pHdr->magic == (ARCH_BITS == 64 ? MH_MAGIC_64 : MH_MAGIC),521 ("%p: magic=%#x\n", pHdr, pHdr->magic), false);522 uint32_t const cCmds = pHdr->ncmds;523 uint32_t const cbCmds = pHdr->sizeofcmds;524 AssertLogRelMsgReturn(cCmds < 16384 && cbCmds < _2M, ("%p: ncmds=%u sizeofcmds=%u\n", pHdr, cCmds, cbCmds), false);525 526 /*527 * First command pass: Locate the symbol table and dynamic symbol table info528 * commands, also calc the slide (load addr - link addr).529 */530 dysymtab_command_t const *pDySymTab = NULL;531 symtab_command_t const *pSymTab = NULL;532 segment_command_64_t const *pFirstSeg = NULL;533 uintptr_t offSlide = 0;534 uint32_t offCmd = 0;535 for (uint32_t iCmd = 0; iCmd < cCmds; iCmd++)536 {537 AssertLogRelMsgReturn(offCmd + sizeof(load_command_t) <= cbCmds,538 ("%p: iCmd=%u offCmd=%#x cbCmds=%#x\n", pHdr, iCmd, offCmd, cbCmds), false);539 load_command_t const * const pCmd = (load_command_t const *)((uintptr_t)(pHdr + 1) + offCmd);540 uint32_t const cbCurCmd = pCmd->cmdsize;541 AssertLogRelMsgReturn(offCmd + cbCurCmd <= cbCmds && cbCurCmd <= cbCmds,542 ("%p: iCmd=%u offCmd=%#x cbCurCmd=%#x cbCmds=%#x\n", pHdr, iCmd, offCmd, cbCurCmd, cbCmds), false);543 offCmd += cbCurCmd;544 545 if (pCmd->cmd == LC_SYMTAB)546 {547 AssertLogRelMsgReturn(!pSymTab, ("%p: pSymTab=%p pCmd=%p\n", pHdr, pSymTab, pCmd), false);548 pSymTab = (symtab_command_t const *)pCmd;549 AssertLogRelMsgReturn(cbCurCmd == sizeof(*pSymTab), ("%p: pSymTab=%p cbCurCmd=%#x\n", pHdr, pCmd, cbCurCmd), false);550 551 }552 else if (pCmd->cmd == LC_DYSYMTAB)553 {554 AssertLogRelMsgReturn(!pDySymTab, ("%p: pDySymTab=%p pCmd=%p\n", pHdr, pDySymTab, pCmd), false);555 pDySymTab = (dysymtab_command_t const *)pCmd;556 AssertLogRelMsgReturn(cbCurCmd == sizeof(*pDySymTab), ("%p: pDySymTab=%p cbCurCmd=%#x\n", pHdr, pCmd, cbCurCmd),557 false);558 }559 else if (pCmd->cmd == LC_SEGMENT_64 && !pFirstSeg) /* ASSUMES the first seg is the one with the header and stuff. */560 {561 /* Note! the fileoff and vmaddr seems to be modified. */562 pFirstSeg = (segment_command_64_t const *)pCmd;563 AssertLogRelMsgReturn(cbCurCmd >= sizeof(*pFirstSeg), ("%p: iCmd=%u cbCurCmd=%#x\n", pHdr, iCmd, cbCurCmd), false);564 AssertLogRelMsgReturn(/*pFirstSeg->fileoff == 0 && */ pFirstSeg->vmsize >= sizeof(*pHdr) + cbCmds,565 ("%p: iCmd=%u fileoff=%llx vmsize=%#llx cbCmds=%#x name=%.16s\n",566 pHdr, iCmd, pFirstSeg->fileoff, pFirstSeg->vmsize, cbCmds, pFirstSeg->segname), false);567 offSlide = (uintptr_t)pHdr - pFirstSeg->vmaddr;568 }569 }570 AssertLogRelMsgReturn(pSymTab, ("%p: no LC_SYMTAB\n", pHdr), false);571 AssertLogRelMsgReturn(pDySymTab, ("%p: no LC_DYSYMTAB\n", pHdr), false);572 AssertLogRelMsgReturn(pFirstSeg, ("%p: no LC_SEGMENT_64\n", pHdr), false);573 574 /*575 * Second command pass: Locate the memory locations of the symbol table, string576 * table and the indirect symbol table by checking LC_SEGMENT_xx.577 */578 macho_nlist_64_t const *paSymbols = NULL;579 uint32_t const offSymbols = pSymTab->symoff;580 uint32_t const cSymbols = pSymTab->nsyms;581 AssertLogRelMsgReturn(cSymbols > 0 && offSymbols >= sizeof(pHdr) + cbCmds,582 ("%p: cSymbols=%#x offSymbols=%#x\n", pHdr, cSymbols, offSymbols), false);583 584 const char *pchStrTab = NULL;585 uint32_t const offStrTab = pSymTab->stroff;586 uint32_t const cbStrTab = pSymTab->strsize;587 AssertLogRelMsgReturn(cbStrTab > 0 && offStrTab >= sizeof(pHdr) + cbCmds,588 ("%p: cbStrTab=%#x offStrTab=%#x\n", pHdr, cbStrTab, offStrTab), false);589 590 uint32_t const *paidxIndirSymbols = NULL;591 uint32_t const offIndirSymbols = pDySymTab->indirectsymboff;592 uint32_t const cIndirSymbols = pDySymTab->nindirectsymb;593 AssertLogRelMsgReturn(cIndirSymbols > 0 && offIndirSymbols >= sizeof(pHdr) + cbCmds,594 ("%p: cIndirSymbols=%#x offIndirSymbols=%#x\n", pHdr, cIndirSymbols, offIndirSymbols), false);595 596 offCmd = 0;597 for (uint32_t iCmd = 0; iCmd < cCmds; iCmd++)598 {599 load_command_t const * const pCmd = (load_command_t const *)((uintptr_t)(pHdr + 1) + offCmd);600 uint32_t const cbCurCmd = pCmd->cmdsize;601 AssertLogRelMsgReturn(offCmd + cbCurCmd <= cbCmds && cbCurCmd <= cbCmds,602 ("%p: iCmd=%u offCmd=%#x cbCurCmd=%#x cbCmds=%#x\n", pHdr, iCmd, offCmd, cbCurCmd, cbCmds), false);603 offCmd += cbCurCmd;604 605 if (pCmd->cmd == LC_SEGMENT_64)606 {607 segment_command_64_t const *pSeg = (segment_command_64_t const *)pCmd;608 AssertLogRelMsgReturn(cbCurCmd >= sizeof(*pSeg), ("%p: iCmd=%u cbCurCmd=%#x\n", pHdr, iCmd, cbCurCmd), false);609 uintptr_t const uPtrSeg = pSeg->vmaddr + offSlide;610 uint64_t const cbSeg = pSeg->vmsize;611 uint64_t const offFile = pSeg->fileoff;612 613 uint64_t offSeg = offSymbols - offFile;614 if (offSeg < cbSeg)615 {616 AssertLogRelMsgReturn(!paSymbols, ("%p: paSymbols=%p uPtrSeg=%p off=%#llx\n", pHdr, paSymbols, uPtrSeg, offSeg),617 false);618 AssertLogRelMsgReturn(offSeg + cSymbols * sizeof(paSymbols[0]) <= cbSeg,619 ("%p: offSeg=%#llx cSymbols=%#x cbSeg=%llx\n", pHdr, offSeg, cSymbols, cbSeg), false);620 paSymbols = (macho_nlist_64_t const *)(uPtrSeg + offSeg);621 }622 623 offSeg = offStrTab - offFile;624 if (offSeg < cbSeg)625 {626 AssertLogRelMsgReturn(!pchStrTab, ("%p: paSymbols=%p uPtrSeg=%p\n", pHdr, pchStrTab, uPtrSeg), false);627 AssertLogRelMsgReturn(offSeg + cbStrTab <= cbSeg,628 ("%p: offSeg=%#llx cbStrTab=%#x cbSeg=%llx\n", pHdr, offSeg, cbStrTab, cbSeg), false);629 pchStrTab = (const char *)(uPtrSeg + offSeg);630 }631 632 offSeg = offIndirSymbols - offFile;633 if (offSeg < cbSeg)634 {635 AssertLogRelMsgReturn(!paidxIndirSymbols,636 ("%p: paidxIndirSymbols=%p uPtrSeg=%p\n", pHdr, paidxIndirSymbols, uPtrSeg), false);637 AssertLogRelMsgReturn(offSeg + cIndirSymbols * sizeof(paidxIndirSymbols[0]) <= cbSeg,638 ("%p: offSeg=%#llx cIndirSymbols=%#x cbSeg=%llx\n", pHdr, offSeg, cIndirSymbols, cbSeg),639 false);640 paidxIndirSymbols = (uint32_t const *)(uPtrSeg + offSeg);641 }642 }643 }644 645 AssertLogRelMsgReturn(paSymbols, ("%p: offSymbols=%#x\n", pHdr, offSymbols), false);646 AssertLogRelMsgReturn(pchStrTab, ("%p: offStrTab=%#x\n", pHdr, offStrTab), false);647 AssertLogRelMsgReturn(paidxIndirSymbols, ("%p: offIndirSymbols=%#x\n", pHdr, offIndirSymbols), false);648 649 /*650 * Third command pass: Process sections of types S_NON_LAZY_SYMBOL_POINTERS651 * and S_LAZY_SYMBOL_POINTERS652 */653 bool fFound = false;654 offCmd = 0;655 for (uint32_t iCmd = 0; iCmd < cCmds; iCmd++)656 {657 load_command_t const * const pCmd = (load_command_t const *)((uintptr_t)(pHdr + 1) + offCmd);658 uint32_t const cbCurCmd = pCmd->cmdsize;659 AssertLogRelMsgReturn(offCmd + cbCurCmd <= cbCmds && cbCurCmd <= cbCmds,660 ("%p: iCmd=%u offCmd=%#x cbCurCmd=%#x cbCmds=%#x\n", pHdr, iCmd, offCmd, cbCurCmd, cbCmds), false);661 offCmd += cbCurCmd;662 if (pCmd->cmd == LC_SEGMENT_64)663 {664 segment_command_64_t const *pSeg = (segment_command_64_t const *)pCmd;665 AssertLogRelMsgReturn(cbCurCmd >= sizeof(*pSeg), ("%p: iCmd=%u cbCurCmd=%#x\n", pHdr, iCmd, cbCurCmd), false);666 uint64_t const uSegAddr = pSeg->vmaddr;667 uint64_t const cbSeg = pSeg->vmsize;668 669 uint32_t const cSections = pSeg->nsects;670 section_64_t const * const paSections = (section_64_t const *)(pSeg + 1);671 AssertLogRelMsgReturn(cSections < _256K && sizeof(*pSeg) + cSections * sizeof(paSections[0]) <= cbCurCmd,672 ("%p: iCmd=%u cSections=%#x cbCurCmd=%#x\n", pHdr, iCmd, cSections, cbCurCmd), false);673 for (uint32_t iSection = 0; iSection < cSections; iSection++)674 {675 if ( paSections[iSection].flags == S_NON_LAZY_SYMBOL_POINTERS676 || paSections[iSection].flags == S_LAZY_SYMBOL_POINTERS)677 {678 uint32_t const idxIndirBase = paSections[iSection].reserved1;679 uint32_t const cEntries = paSections[iSection].size / sizeof(uintptr_t);680 AssertLogRelMsgReturn(idxIndirBase <= cIndirSymbols && idxIndirBase + cEntries <= cIndirSymbols,681 ("%p: idxIndirBase=%#x cEntries=%#x cIndirSymbols=%#x\n",682 pHdr, idxIndirBase, cEntries, cIndirSymbols), false);683 uint64_t const uSecAddr = paSections[iSection].addr;684 uint64_t const offInSeg = uSecAddr - uSegAddr;685 AssertLogRelMsgReturn(offInSeg < cbSeg && offInSeg + cEntries * sizeof(uintptr_t) <= cbSeg,686 ("%p: offInSeg=%#llx cEntries=%#x cbSeg=%#llx\n", pHdr, offInSeg, cEntries, cbSeg),687 false);688 uintptr_t *pauPtrs = (uintptr_t *)(uSecAddr + offSlide);689 for (uint32_t iEntry = 0; iEntry < cEntries; iEntry++)690 {691 uint32_t const idxSym = paidxIndirSymbols[idxIndirBase + iEntry];692 if (idxSym < cSymbols)693 {694 macho_nlist_64_t const * const pSym = &paSymbols[idxSym];695 const char * const pszName = pSym->n_un.n_strx < cbStrTab696 ? &pchStrTab[pSym->n_un.n_strx] : "!invalid symtab offset!";697 if (strcmp(pszName, pszSymbol) == 0)698 {699 pauPtrs[iEntry] = uNewValue;700 fFound = true;701 break;702 }703 }704 else705 AssertMsg(idxSym == INDIRECT_SYMBOL_LOCAL || idxSym == INDIRECT_SYMBOL_ABS, ("%#x\n", idxSym));706 }707 }708 }709 }710 }711 AssertLogRel(fFound);712 return fFound;713 }714 715 /**716 * Mac OS X: Really ugly hack to bypass a set-uid check in AppKit.717 *718 * This will modify the issetugid() function to always return zero. This must719 * be done _before_ AppKit is initialized, otherwise it will refuse to play ball720 * with us as it distrusts set-uid processes since Snow Leopard. We, however,721 * have carefully dropped all root privileges at this point and there should be722 * no reason for any security concern here.723 */724 static void hideSetUidRootFromAppKit()725 {726 void *pvAddr;727 /* Find issetguid() and make it always return 0 by modifying the code: */728 # if 0729 pvAddr = dlsym(RTLD_DEFAULT, "issetugid");730 int rc = mprotect((void *)((uintptr_t)pvAddr & ~(uintptr_t)0xfff), 0x2000, PROT_WRITE | PROT_READ | PROT_EXEC);731 if (!rc)732 ASMAtomicWriteU32((volatile uint32_t *)pvAddr, 0xccc3c031); /* xor eax, eax; ret; int3 */733 else734 # endif735 {736 /* Failing that, find AppKit and patch its import table: */737 void *pvAppKit = dlopen("/System/Library/Frameworks/AppKit.framework/AppKit", RTLD_NOLOAD);738 pvAddr = dlsym(pvAppKit, "NSApplicationMain");739 Dl_info Info = {0};740 if ( dladdr(pvAddr, &Info)741 && Info.dli_fbase != NULL)742 {743 if (!patchExtSym((mach_header_64_t *)Info.dli_fbase, "_issetugid", (uintptr_t)&issetugid_for_AppKit))744 write(2, RT_STR_TUPLE("WARNING: Failed to patch issetugid in AppKit! (patchExtSym)\n"));745 # ifdef DEBUG746 else747 write(2, RT_STR_TUPLE("INFO: Successfully patched _issetugid import for AppKit!\n"));748 # endif749 }750 else751 write(2, RT_STR_TUPLE("WARNING: Failed to patch issetugid in AppKit! (dladdr)\n"));752 }753 754 }755 756 #endif /* RT_OS_DARWIN */757 486 758 487 … … 1161 890 const char *pcszNameOrUUID = NULL; 1162 891 1163 #if 0 //def RT_OS_DARWIN - see above1164 hideSetUidRootFromAppKit();1165 #endif1166 1167 892 // parse the command line 1168 893 int ch;
Note:
See TracChangeset
for help on using the changeset viewer.