third_party/virtualbox/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp
/**
 * Returns the full path to the executable in g_szSupLibHardenedExePath.
 *
 * @returns IPRT status code.
 */
Returns the full path to the executable in g_szSupLibHardenedExePath.
@returns IPRT status code.
Returns the full path to the executable in g_szSupLibHardenedExePath . @returns IPRT status code .
static void supR3HardenedGetFullExePath(void)
{
#if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD) || defined(RT_OS_SOLARIS)
# ifdef RT_OS_LINUX
    int cchLink = readlink("/proc/self/exe", &g_szSupLibHardenedExePath[0], sizeof(g_szSupLibHardenedExePath) - 1);
# elif defined(RT_OS_SOLARIS)
    char szFileBuf[PATH_MAX + 1];
    sprintf(szFileBuf, "/proc/%ld/path/a.out", (long)getpid());
    int cchLink = readlink(szFileBuf, &g_szSupLibHardenedExePath[0], sizeof(g_szSupLibHardenedExePath) - 1);
# else 
    int aiName[4];
    aiName[0] = CTL_KERN;
    aiName[1] = KERN_PROC;
    aiName[2] = KERN_PROC_PATHNAME;
    aiName[3] = getpid();
    size_t cbPath = sizeof(g_szSupLibHardenedExePath);
    if (sysctl(aiName, RT_ELEMENTS(aiName), g_szSupLibHardenedExePath, &cbPath, NULL, 0) < 0)
        supR3HardenedFatal("supR3HardenedExecDir: sysctl failed\n");
    g_szSupLibHardenedExePath[sizeof(g_szSupLibHardenedExePath) - 1] = '\0';
    int cchLink = suplibHardenedStrLen(g_szSupLibHardenedExePath); 
# endif
    if (cchLink < 0 || cchLink == sizeof(g_szSupLibHardenedExePath) - 1)
        supR3HardenedFatal("supR3HardenedExecDir: couldn't read \"%s\", errno=%d cchLink=%d\n",
                            g_szSupLibHardenedExePath, errno, cchLink);
    g_szSupLibHardenedExePath[cchLink] = '\0';
#elif defined(RT_OS_OS2) || defined(RT_OS_L4)
    _execname(g_szSupLibHardenedExePath, sizeof(g_szSupLibHardenedExePath));
#elif defined(RT_OS_DARWIN)
    const char *pszImageName = _dyld_get_image_name(0);
    if (!pszImageName)
        supR3HardenedFatal("supR3HardenedExecDir: _dyld_get_image_name(0) failed\n");
    size_t cchImageName = suplibHardenedStrLen(pszImageName);
    if (!cchImageName || cchImageName >= sizeof(g_szSupLibHardenedExePath))
        supR3HardenedFatal("supR3HardenedExecDir: _dyld_get_image_name(0) failed, cchImageName=%d\n", cchImageName);
    suplibHardenedMemCopy(g_szSupLibHardenedExePath, pszImageName, cchImageName + 1);
#elif defined(RT_OS_WINDOWS)
    char *pszDst = g_szSupLibHardenedExePath;
    int rc = RTUtf16ToUtf8Ex(g_wszSupLibHardenedExePath, RTSTR_MAX, &pszDst, sizeof(g_szSupLibHardenedExePath), NULL);
    if (RT_FAILURE(rc))
        supR3HardenedFatal("supR3HardenedExecDir: RTUtf16ToUtf8Ex failed, rc=%Rrc\n", rc);
#else
# error needs porting.
#endif
    suplibHardenedStrCopy(g_szSupLibHardenedAppBinPath, g_szSupLibHardenedExePath);
    suplibHardenedPathStripFilename(g_szSupLibHardenedAppBinPath);
    g_offSupLibHardenedExecName = suplibHardenedStrLen(g_szSupLibHardenedAppBinPath);
    while (RTPATH_IS_SEP(g_szSupLibHardenedExePath[g_offSupLibHardenedExecName]))
           g_offSupLibHardenedExecName++;
    g_cchSupLibHardenedExecName = suplibHardenedStrLen(&g_szSupLibHardenedExePath[g_offSupLibHardenedExecName]);
    if (g_enmSupR3HardenedMainState < SUPR3HARDENEDMAINSTATE_HARDENED_MAIN_CALLED)
        supR3HardenedFatal("supR3HardenedExecDir: Called before SUPR3HardenedMain! (%d)\n", g_enmSupR3HardenedMainState);
    switch (g_fSupHardenedMain & SUPSECMAIN_FLAGS_LOC_MASK)
    {
        case SUPSECMAIN_FLAGS_LOC_APP_BIN:
            break;
        case SUPSECMAIN_FLAGS_LOC_TESTCASE:
            suplibHardenedPathStripFilename(g_szSupLibHardenedAppBinPath);
            break;
#ifdef RT_OS_DARWIN
        case SUPSECMAIN_FLAGS_LOC_OSX_HLP_APP:
        {
            static const RTSTRTUPLE s_aComponentsToSkip[] =
            { { RT_STR_TUPLE("MacOS") }, { RT_STR_TUPLE("Contents") }, { NULL , 0 }, { RT_STR_TUPLE("Resources") } };
            size_t cchPath = suplibHardenedStrLen(g_szSupLibHardenedAppBinPath);
            for (uintptr_t i = 0; i < RT_ELEMENTS(s_aComponentsToSkip); i++)
            {
                while (cchPath > 1 && g_szSupLibHardenedAppBinPath[cchPath - 1] == '/')
                    cchPath--;
                size_t const cchMatch = s_aComponentsToSkip[i].cch;
                if (cchMatch > 0)
                {
                    if (   cchPath >= cchMatch + sizeof("VirtualBox.app/Contents")
                        && g_szSupLibHardenedAppBinPath[cchPath - cchMatch - 1] == '/'
                        && suplibHardenedMemComp(&g_szSupLibHardenedAppBinPath[cchPath - cchMatch],
                                                 s_aComponentsToSkip[i].psz, cchMatch) == 0)
                        cchPath -= cchMatch;
                    else
                        supR3HardenedFatal("supR3HardenedExecDir: Bad helper app path (tail component #%u '%s'): %s\n",
                                           i, s_aComponentsToSkip[i].psz, g_szSupLibHardenedAppBinPath);
                }
                else if (   cchPath > g_cchSupLibHardenedExecName  + sizeof("VirtualBox.app/Contents/Resources/.app")
                         && suplibHardenedMemComp(&g_szSupLibHardenedAppBinPath[cchPath - 4], ".app", 4) == 0
                         && suplibHardenedMemComp(&g_szSupLibHardenedAppBinPath[cchPath - 4 - g_cchSupLibHardenedExecName],
                                                  &g_szSupLibHardenedExePath[g_offSupLibHardenedExecName],
                                                  g_cchSupLibHardenedExecName) == 0)
                    cchPath -= g_cchSupLibHardenedExecName + 4;
                else
                    supR3HardenedFatal("supR3HardenedExecDir: Bad helper app path (tail component #%u '%s.app'): %s\n",
                                       i, &g_szSupLibHardenedExePath[g_offSupLibHardenedExecName], g_szSupLibHardenedAppBinPath);
            }
            suplibHardenedMemCopy(&g_szSupLibHardenedAppBinPath[cchPath], "MacOS", sizeof("MacOS"));
            break;
        }
#endif 
        default:
            supR3HardenedFatal("supR3HardenedExecDir: Unknown program binary location: %#x\n", g_fSupHardenedMain);
    }
}
static void supR3HardenedGetFullExePath ( void ) { #if defined ( RT_OS_LINUX ) || defined ( RT_OS_FREEBSD ) || defined ( RT_OS_SOLARIS ) # ifdef RT_OS_LINUX int cchLink = readlink ( " " , & g_szSupLibHardenedExePath [ 0 ] , sizeof ( g_szSupLibHardenedExePath ) - 1 ) ; # elif defined ( RT_OS_SOLARIS ) char szFileBuf [ PATH_MAX + 1 ] ; sprintf ( szFileBuf , " " , ( long ) getpid ( ) ) ; int cchLink = readlink ( szFileBuf , & g_szSupLibHardenedExePath [ 0 ] , sizeof ( g_szSupLibHardenedExePath ) - 1 ) ; # else int aiName [ 4 ] ; aiName [ 0 ] = CTL_KERN ; aiName [ 1 ] = KERN_PROC ; aiName [ 2 ] = KERN_PROC_PATHNAME ; aiName [ 3 ] = getpid ( ) ; size_t cbPath = sizeof ( g_szSupLibHardenedExePath ) ; if ( sysctl ( aiName , RT_ELEMENTS ( aiName ) , g_szSupLibHardenedExePath , & cbPath , NULL , 0 ) < 0 ) supR3HardenedFatal ( " \n " ) ; g_szSupLibHardenedExePath [ sizeof ( g_szSupLibHardenedExePath ) - 1 ] = ' \0 ' ; int cchLink = suplibHardenedStrLen ( g_szSupLibHardenedExePath ) ; # endif if ( cchLink < 0 || cchLink == sizeof ( g_szSupLibHardenedExePath ) - 1 ) supR3HardenedFatal ( " \" \" \n " , g_szSupLibHardenedExePath , errno , cchLink ) ; g_szSupLibHardenedExePath [ cchLink ] = ' \0 ' ; #elif defined ( RT_OS_OS2 ) || defined ( RT_OS_L4 ) _execname ( g_szSupLibHardenedExePath , sizeof ( g_szSupLibHardenedExePath ) ) ; #elif defined ( RT_OS_DARWIN ) const char * pszImageName = _dyld_get_image_name ( 0 ) ; if ( ! pszImageName ) supR3HardenedFatal ( " \n " ) ; size_t cchImageName = suplibHardenedStrLen ( pszImageName ) ; if ( ! cchImageName || cchImageName >= sizeof ( g_szSupLibHardenedExePath ) ) supR3HardenedFatal ( " \n " , cchImageName ) ; suplibHardenedMemCopy ( g_szSupLibHardenedExePath , pszImageName , cchImageName + 1 ) ; #elif defined ( RT_OS_WINDOWS ) char * pszDst = g_szSupLibHardenedExePath ; int rc = RTUtf16ToUtf8Ex ( g_wszSupLibHardenedExePath , RTSTR_MAX , & pszDst , sizeof ( g_szSupLibHardenedExePath ) , NULL ) ; if ( RT_FAILURE ( rc ) ) supR3HardenedFatal ( " \n " , rc ) ; #else # error  needs porting. #endif suplibHardenedStrCopy ( g_szSupLibHardenedAppBinPath , g_szSupLibHardenedExePath ) ; suplibHardenedPathStripFilename ( g_szSupLibHardenedAppBinPath ) ; g_offSupLibHardenedExecName = suplibHardenedStrLen ( g_szSupLibHardenedAppBinPath ) ; while ( RTPATH_IS_SEP ( g_szSupLibHardenedExePath [ g_offSupLibHardenedExecName ] ) ) g_offSupLibHardenedExecName ++ ; g_cchSupLibHardenedExecName = suplibHardenedStrLen ( & g_szSupLibHardenedExePath [ g_offSupLibHardenedExecName ] ) ; if ( g_enmSupR3HardenedMainState < SUPR3HARDENEDMAINSTATE_HARDENED_MAIN_CALLED ) supR3HardenedFatal ( " \n " , g_enmSupR3HardenedMainState ) ; switch ( g_fSupHardenedMain & SUPSECMAIN_FLAGS_LOC_MASK ) { case SUPSECMAIN_FLAGS_LOC_APP_BIN : break ; case SUPSECMAIN_FLAGS_LOC_TESTCASE : suplibHardenedPathStripFilename ( g_szSupLibHardenedAppBinPath ) ; break ; #ifdef RT_OS_DARWIN case SUPSECMAIN_FLAGS_LOC_OSX_HLP_APP : { static const RTSTRTUPLE s_aComponentsToSkip [ ] = { { RT_STR_TUPLE ( " " ) } , { RT_STR_TUPLE ( " " ) } , { NULL , 0 } , { RT_STR_TUPLE ( " " ) } } ; size_t cchPath = suplibHardenedStrLen ( g_szSupLibHardenedAppBinPath ) ; for ( uintptr_t i = 0 ; i < RT_ELEMENTS ( s_aComponentsToSkip ) ; i ++ ) { while ( cchPath > 1 && g_szSupLibHardenedAppBinPath [ cchPath - 1 ] == ' ' ) cchPath -- ; size_t const cchMatch = s_aComponentsToSkip [ i ] . cch ; if ( cchMatch > 0 ) { if ( cchPath >= cchMatch + sizeof ( " " ) && g_szSupLibHardenedAppBinPath [ cchPath - cchMatch - 1 ] == ' ' && suplibHardenedMemComp ( & g_szSupLibHardenedAppBinPath [ cchPath - cchMatch ] , s_aComponentsToSkip [ i ] . psz , cchMatch ) == 0 ) cchPath -= cchMatch ; else supR3HardenedFatal ( " \n " , i , s_aComponentsToSkip [ i ] . psz , g_szSupLibHardenedAppBinPath ) ; } else if ( cchPath > g_cchSupLibHardenedExecName + sizeof ( " " ) && suplibHardenedMemComp ( & g_szSupLibHardenedAppBinPath [ cchPath - 4 ] , " " , 4 ) == 0 && suplibHardenedMemComp ( & g_szSupLibHardenedAppBinPath [ cchPath - 4 - g_cchSupLibHardenedExecName ] , & g_szSupLibHardenedExePath [ g_offSupLibHardenedExecName ] , g_cchSupLibHardenedExecName ) == 0 ) cchPath -= g_cchSupLibHardenedExecName + 4 ; else supR3HardenedFatal ( " \n " , i , & g_szSupLibHardenedExePath [ g_offSupLibHardenedExecName ] , g_szSupLibHardenedAppBinPath ) ; } suplibHardenedMemCopy ( & g_szSupLibHardenedAppBinPath [ cchPath ] , " " , sizeof ( " " ) ) ; break ; } #endif default : supR3HardenedFatal ( " \n " , g_fSupHardenedMain ) ; } }
Returns the full path to the executable in g_szSupLibHardenedExePath.
Returns the full path to the executable in g_szSupLibHardenedExePath .
/*
     * Get the program filename.
     *
     * Most UNIXes have no API for obtaining the executable path, but provides a symbolic
     * link in the proc file system that tells who was exec'ed. The bad thing about this
     * is that we have to use readlink, one of the weirder UNIX APIs.
     *
     * Darwin, OS/2 and Windows all have proper APIs for getting the program file name.
     */ /* RT_OS_FREEBSD */ /* paranoid? can't we use cbPath? */ /*
     * Determine the application binary directory location.
     */ /* We must ascend to the parent bundle's Contents directory then decend into its MacOS: */ /*some.app*/ /* RT_OS_DARWIN */