Changeset 85488 in vbox for trunk/src/VBox/Frontends
- Timestamp:
- Jul 28, 2020 1:38:39 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp
r82968 r85488 529 529 530 530 #ifdef RT_OS_DARWIN 531 532 # include <unistd.h> 533 # include <stdio.h> 534 # include <dlfcn.h> 535 # include <iprt/formats/mach-o.h> 536 537 /** 538 * Override this one to try hide the fact that we're setuid to root 539 * orginially. 540 */ 541 int issetugid_for_AppKit(void) 542 { 543 Dl_info Info = {0}; 544 char szMsg[512]; 545 size_t cchMsg; 546 const void * uCaller = __builtin_return_address(0); 547 if (dladdr(uCaller, &Info)) 548 cchMsg = snprintf(szMsg, sizeof(szMsg), "DEBUG: issetugid_for_AppKit was called by %p %s::%s+%p (via %p)\n", 549 uCaller, Info.dli_fname, Info.dli_sname, (void *)((uintptr_t)uCaller - (uintptr_t)Info.dli_saddr), __builtin_return_address(1)); 550 else 551 cchMsg = snprintf(szMsg, sizeof(szMsg), "DEBUG: issetugid_for_AppKit was called by %p (via %p)\n", uCaller, __builtin_return_address(1)); 552 write(2, szMsg, cchMsg); 553 return 0; 554 } 555 556 static bool patchExtSym(mach_header_64_t *pHdr, const char *pszSymbol, uintptr_t uNewValue) 557 { 558 /* 559 * First do some basic header checks and the scan the load 560 * commands for the symbol table info. 561 */ 562 AssertLogRelMsgReturn(pHdr->magic == (ARCH_BITS == 64 ? MH_MAGIC_64 : MH_MAGIC), 563 ("%p: magic=%#x\n", pHdr, pHdr->magic), false); 564 uint32_t const cCmds = pHdr->ncmds; 565 uint32_t const cbCmds = pHdr->sizeofcmds; 566 AssertLogRelMsgReturn(cCmds < 16384 && cbCmds < _2M, ("%p: ncmds=%u sizeofcmds=%u\n", pHdr, cCmds, cbCmds), false); 567 568 /* 569 * First command pass: Locate the symbol table and dynamic symbol table info 570 * commands, also calc the slide (load addr - link addr). 571 */ 572 dysymtab_command_t const *pDySymTab = NULL; 573 symtab_command_t const *pSymTab = NULL; 574 segment_command_64_t const *pFirstSeg = NULL; 575 uintptr_t offSlide = 0; 576 uint32_t offCmd = 0; 577 for (uint32_t iCmd = 0; iCmd < cCmds; iCmd++) 578 { 579 AssertLogRelMsgReturn(offCmd + sizeof(load_command_t) <= cbCmds, 580 ("%p: iCmd=%u offCmd=%#x cbCmds=%#x\n", pHdr, iCmd, offCmd, cbCmds), false); 581 load_command_t const * const pCmd = (load_command_t const *)((uintptr_t)(pHdr + 1) + offCmd); 582 uint32_t const cbCurCmd = pCmd->cmdsize; 583 AssertLogRelMsgReturn(offCmd + cbCurCmd <= cbCmds && cbCurCmd <= cbCmds, 584 ("%p: iCmd=%u offCmd=%#x cbCurCmd=%#x cbCmds=%#x\n", pHdr, iCmd, offCmd, cbCurCmd, cbCmds), false); 585 offCmd += cbCurCmd; 586 587 if (pCmd->cmd == LC_SYMTAB) 588 { 589 AssertLogRelMsgReturn(!pSymTab, ("%p: pSymTab=%p pCmd=%p\n", pHdr, pSymTab, pCmd), false); 590 pSymTab = (symtab_command_t const *)pCmd; 591 AssertLogRelMsgReturn(cbCurCmd == sizeof(*pSymTab), ("%p: pSymTab=%p cbCurCmd=%#x\n", pHdr, pCmd, cbCurCmd), false); 592 593 } 594 else if (pCmd->cmd == LC_DYSYMTAB) 595 { 596 AssertLogRelMsgReturn(!pDySymTab, ("%p: pDySymTab=%p pCmd=%p\n", pHdr, pDySymTab, pCmd), false); 597 pDySymTab = (dysymtab_command_t const *)pCmd; 598 AssertLogRelMsgReturn(cbCurCmd == sizeof(*pDySymTab), ("%p: pDySymTab=%p cbCurCmd=%#x\n", pHdr, pCmd, cbCurCmd), 599 false); 600 } 601 else if (pCmd->cmd == LC_SEGMENT_64 && !pFirstSeg) /* ASSUMES the first seg is the one with the header and stuff. */ 602 { 603 /* Note! the fileoff and vmaddr seems to be modified. */ 604 pFirstSeg = (segment_command_64_t const *)pCmd; 605 AssertLogRelMsgReturn(cbCurCmd >= sizeof(*pFirstSeg), ("%p: iCmd=%u cbCurCmd=%#x\n", pHdr, iCmd, cbCurCmd), false); 606 AssertLogRelMsgReturn(/*pFirstSeg->fileoff == 0 && */ pFirstSeg->vmsize >= sizeof(*pHdr) + cbCmds, 607 ("%p: iCmd=%u fileoff=%llx vmsize=%#llx cbCmds=%#x name=%.16s\n", 608 pHdr, iCmd, pFirstSeg->fileoff, pFirstSeg->vmsize, cbCmds, pFirstSeg->segname), false); 609 offSlide = (uintptr_t)pHdr - pFirstSeg->vmaddr; 610 } 611 } 612 AssertLogRelMsgReturn(pSymTab, ("%p: no LC_SYMTAB\n", pHdr), false); 613 AssertLogRelMsgReturn(pDySymTab, ("%p: no LC_DYSYMTAB\n", pHdr), false); 614 AssertLogRelMsgReturn(pFirstSeg, ("%p: no LC_SEGMENT_64\n", pHdr), false); 615 616 /* 617 * Second command pass: Locate the memory locations of the symbol table, string 618 * table and the indirect symbol table by checking LC_SEGMENT_xx. 619 */ 620 macho_nlist_64_t const *paSymbols = NULL; 621 uint32_t const offSymbols = pSymTab->symoff; 622 uint32_t const cSymbols = pSymTab->nsyms; 623 AssertLogRelMsgReturn(cSymbols > 0 && offSymbols >= sizeof(pHdr) + cbCmds, 624 ("%p: cSymbols=%#x offSymbols=%#x\n", pHdr, cSymbols, offSymbols), false); 625 626 const char *pchStrTab = NULL; 627 uint32_t const offStrTab = pSymTab->stroff; 628 uint32_t const cbStrTab = pSymTab->strsize; 629 AssertLogRelMsgReturn(cbStrTab > 0 && offStrTab >= sizeof(pHdr) + cbCmds, 630 ("%p: cbStrTab=%#x offStrTab=%#x\n", pHdr, cbStrTab, offStrTab), false); 631 632 uint32_t const *paidxIndirSymbols = NULL; 633 uint32_t const offIndirSymbols = pDySymTab->indirectsymboff; 634 uint32_t const cIndirSymbols = pDySymTab->nindirectsymb; 635 AssertLogRelMsgReturn(cIndirSymbols > 0 && offIndirSymbols >= sizeof(pHdr) + cbCmds, 636 ("%p: cIndirSymbols=%#x offIndirSymbols=%#x\n", pHdr, cIndirSymbols, offIndirSymbols), false); 637 638 offCmd = 0; 639 for (uint32_t iCmd = 0; iCmd < cCmds; iCmd++) 640 { 641 load_command_t const * const pCmd = (load_command_t const *)((uintptr_t)(pHdr + 1) + offCmd); 642 uint32_t const cbCurCmd = pCmd->cmdsize; 643 AssertLogRelMsgReturn(offCmd + cbCurCmd <= cbCmds && cbCurCmd <= cbCmds, 644 ("%p: iCmd=%u offCmd=%#x cbCurCmd=%#x cbCmds=%#x\n", pHdr, iCmd, offCmd, cbCurCmd, cbCmds), false); 645 offCmd += cbCurCmd; 646 647 if (pCmd->cmd == LC_SEGMENT_64) 648 { 649 segment_command_64_t const *pSeg = (segment_command_64_t const *)pCmd; 650 AssertLogRelMsgReturn(cbCurCmd >= sizeof(*pSeg), ("%p: iCmd=%u cbCurCmd=%#x\n", pHdr, iCmd, cbCurCmd), false); 651 uintptr_t const uPtrSeg = pSeg->vmaddr + offSlide; 652 uint64_t const cbSeg = pSeg->vmsize; 653 uint64_t const offFile = pSeg->fileoff; 654 655 uint64_t offSeg = offSymbols - offFile; 656 if (offSeg < cbSeg) 657 { 658 AssertLogRelMsgReturn(!paSymbols, ("%p: paSymbols=%p uPtrSeg=%p off=%#llx\n", pHdr, paSymbols, uPtrSeg, offSeg), 659 false); 660 AssertLogRelMsgReturn(offSeg + cSymbols * sizeof(paSymbols[0]) <= cbSeg, 661 ("%p: offSeg=%#llx cSymbols=%#x cbSeg=%llx\n", pHdr, offSeg, cSymbols, cbSeg), false); 662 paSymbols = (macho_nlist_64_t const *)(uPtrSeg + offSeg); 663 } 664 665 offSeg = offStrTab - offFile; 666 if (offSeg < cbSeg) 667 { 668 AssertLogRelMsgReturn(!pchStrTab, ("%p: paSymbols=%p uPtrSeg=%p\n", pHdr, pchStrTab, uPtrSeg), false); 669 AssertLogRelMsgReturn(offSeg + cbStrTab <= cbSeg, 670 ("%p: offSeg=%#llx cbStrTab=%#x cbSeg=%llx\n", pHdr, offSeg, cbStrTab, cbSeg), false); 671 pchStrTab = (const char *)(uPtrSeg + offSeg); 672 } 673 674 offSeg = offIndirSymbols - offFile; 675 if (offSeg < cbSeg) 676 { 677 AssertLogRelMsgReturn(!paidxIndirSymbols, 678 ("%p: paidxIndirSymbols=%p uPtrSeg=%p\n", pHdr, paidxIndirSymbols, uPtrSeg), false); 679 AssertLogRelMsgReturn(offSeg + cIndirSymbols * sizeof(paidxIndirSymbols[0]) <= cbSeg, 680 ("%p: offSeg=%#llx cIndirSymbols=%#x cbSeg=%llx\n", pHdr, offSeg, cIndirSymbols, cbSeg), 681 false); 682 paidxIndirSymbols = (uint32_t const *)(uPtrSeg + offSeg); 683 } 684 } 685 } 686 687 AssertLogRelMsgReturn(paSymbols, ("%p: offSymbols=%#x\n", pHdr, offSymbols), false); 688 AssertLogRelMsgReturn(pchStrTab, ("%p: offStrTab=%#x\n", pHdr, offStrTab), false); 689 AssertLogRelMsgReturn(paidxIndirSymbols, ("%p: offIndirSymbols=%#x\n", pHdr, offIndirSymbols), false); 690 691 /* 692 * Third command pass: Process sections of types S_NON_LAZY_SYMBOL_POINTERS 693 * and S_LAZY_SYMBOL_POINTERS 694 */ 695 bool fFound = false; 696 offCmd = 0; 697 for (uint32_t iCmd = 0; iCmd < cCmds; iCmd++) 698 { 699 load_command_t const * const pCmd = (load_command_t const *)((uintptr_t)(pHdr + 1) + offCmd); 700 uint32_t const cbCurCmd = pCmd->cmdsize; 701 AssertLogRelMsgReturn(offCmd + cbCurCmd <= cbCmds && cbCurCmd <= cbCmds, 702 ("%p: iCmd=%u offCmd=%#x cbCurCmd=%#x cbCmds=%#x\n", pHdr, iCmd, offCmd, cbCurCmd, cbCmds), false); 703 offCmd += cbCurCmd; 704 if (pCmd->cmd == LC_SEGMENT_64) 705 { 706 segment_command_64_t const *pSeg = (segment_command_64_t const *)pCmd; 707 AssertLogRelMsgReturn(cbCurCmd >= sizeof(*pSeg), ("%p: iCmd=%u cbCurCmd=%#x\n", pHdr, iCmd, cbCurCmd), false); 708 uint64_t const uSegAddr = pSeg->vmaddr; 709 uint64_t const cbSeg = pSeg->vmsize; 710 711 uint32_t const cSections = pSeg->nsects; 712 section_64_t const * const paSections = (section_64_t const *)(pSeg + 1); 713 AssertLogRelMsgReturn(cSections < _256K && sizeof(*pSeg) + cSections * sizeof(paSections[0]) <= cbCurCmd, 714 ("%p: iCmd=%u cSections=%#x cbCurCmd=%#x\n", pHdr, iCmd, cSections, cbCurCmd), false); 715 for (uint32_t iSection = 0; iSection < cSections; iSection++) 716 { 717 if ( paSections[iSection].flags == S_NON_LAZY_SYMBOL_POINTERS 718 || paSections[iSection].flags == S_LAZY_SYMBOL_POINTERS) 719 { 720 uint32_t const idxIndirBase = paSections[iSection].reserved1; 721 uint32_t const cEntries = paSections[iSection].size / sizeof(uintptr_t); 722 AssertLogRelMsgReturn(idxIndirBase <= cIndirSymbols && idxIndirBase + cEntries <= cIndirSymbols, 723 ("%p: idxIndirBase=%#x cEntries=%#x cIndirSymbols=%#x\n", 724 pHdr, idxIndirBase, cEntries, cIndirSymbols), false); 725 uint64_t const uSecAddr = paSections[iSection].addr; 726 uint64_t const offInSeg = uSecAddr - uSegAddr; 727 AssertLogRelMsgReturn(offInSeg < cbSeg && offInSeg + cEntries * sizeof(uintptr_t) <= cbSeg, 728 ("%p: offInSeg=%#llx cEntries=%#x cbSeg=%#llx\n", pHdr, offInSeg, cEntries, cbSeg), 729 false); 730 uintptr_t *pauPtrs = (uintptr_t *)(uSecAddr + offSlide); 731 for (uint32_t iEntry = 0; iEntry < cEntries; iEntry++) 732 { 733 uint32_t const idxSym = paidxIndirSymbols[idxIndirBase + iEntry]; 734 if (idxSym < cSymbols) 735 { 736 macho_nlist_64_t const * const pSym = &paSymbols[idxSym]; 737 const char * const pszName = pSym->n_un.n_strx < cbStrTab 738 ? &pchStrTab[pSym->n_un.n_strx] : "!invalid symtab offset!"; 739 if (strcmp(pszName, pszSymbol) == 0) 740 { 741 pauPtrs[iEntry] = uNewValue; 742 fFound = true; 743 break; 744 } 745 } 746 else 747 AssertMsg(idxSym == INDIRECT_SYMBOL_LOCAL || idxSym == INDIRECT_SYMBOL_ABS, ("%#x\n", idxSym)); 748 } 749 } 750 } 751 } 752 } 753 AssertLogRel(fFound); 754 return fFound; 755 } 756 531 757 /** 532 758 * Mac OS X: Really ugly hack to bypass a set-uid check in AppKit. … … 540 766 static void hideSetUidRootFromAppKit() 541 767 { 768 void *pvAddr; 542 769 /* Find issetguid() and make it always return 0 by modifying the code: */ 543 void *pvAddr = dlsym(RTLD_DEFAULT, "issetugid"); 770 # if 0 771 pvAddr = dlsym(RTLD_DEFAULT, "issetugid"); 544 772 int rc = mprotect((void *)((uintptr_t)pvAddr & ~(uintptr_t)0xfff), 0x2000, PROT_WRITE | PROT_READ | PROT_EXEC); 545 773 if (!rc) 546 774 ASMAtomicWriteU32((volatile uint32_t *)pvAddr, 0xccc3c031); /* xor eax, eax; ret; int3 */ 775 else 776 # endif 777 { 778 /* Failing that, find AppKit and patch its import table: */ 779 void *pvAppKit = dlopen("/System/Library/Frameworks/AppKit.framework/AppKit", RTLD_NOLOAD); 780 pvAddr = dlsym(pvAppKit, "NSApplicationMain"); 781 Dl_info Info = {0}; 782 if ( dladdr(pvAddr, &Info) 783 && Info.dli_fbase != NULL) 784 { 785 if (!patchExtSym((mach_header_64_t *)Info.dli_fbase, "_issetugid", (uintptr_t)&issetugid_for_AppKit)) 786 write(2, RT_STR_TUPLE("WARNING: Failed to patch issetugid in AppKit! (patchExtSym)\n")); 787 # ifdef DEBUG 788 else 789 write(2, RT_STR_TUPLE("INFO: Successfully patched _issetugid import for AppKit!\n")); 790 # endif 791 } 792 else 793 write(2, RT_STR_TUPLE("WARNING: Failed to patch issetugid in AppKit! (dladdr)\n")); 794 } 795 547 796 } 797 548 798 #endif /* RT_OS_DARWIN */ 549 799
Note:
See TracChangeset
for help on using the changeset viewer.