VirtualBox

Changeset 79011 in vbox


Ignore:
Timestamp:
Jun 5, 2019 7:22:09 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
131156
Message:

IPRT/process-creation-posix.cpp: Try to dynamically resolve crypt_r on linux. ticketref:18682

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/posix/process-creation-posix.cpp

    r79010 r79011  
    3131#define LOG_GROUP RTLOGGROUP_PROCESS
    3232#include <iprt/cdefs.h>
     33#ifdef RT_OS_LINUX
     34# define IPRT_WITH_DYNAMIC_CRYPT_R
     35#endif
     36#if (defined(RT_OS_LINUX) || defined(RT_OS_OS2)) && !defined(_GNU_SOURCE)
     37# define _GNU_SOURCE
     38#endif
    3339
    3440#include <unistd.h>
     
    95101#include <iprt/err.h>
    96102#include <iprt/file.h>
     103#ifdef IPRT_WITH_DYNAMIC_CRYPT_R
     104# include <iprt/ldr.h>
     105#endif
    97106#include <iprt/log.h>
    98107#include <iprt/path.h>
     
    165174}
    166175#endif /* RT_OS_DARWIN */
     176
     177
     178#ifdef IPRT_WITH_DYNAMIC_CRYPT_R
     179/** Pointer to crypt_r(). */
     180typedef char *(*PFNCRYPTR)(const char *, const char *, struct crypt_data *);
     181
     182/**
     183 * Wrapper for resolving and calling crypt_r dynamcially.
     184 *
     185 * The reason for this is that fedora 30+ wants to use libxcrypt rather than the
     186 * glibc libcrypt.  The two libraries has different crypt_data sizes and layout,
     187 * so we allocate a 256KB data block to be on the safe size (caller does this).
     188 */
     189static char *rtProcDynamicCryptR(const char *pszKey, const char *pszSalt, struct crypt_data *pData)
     190{
     191    static PFNCRYPTR volatile s_pfnCryptR = NULL;
     192    PFNCRYPTR pfnCryptR = s_pfnCryptR;
     193    if (pfnCryptR)
     194        return pfnCryptR(pszKey, pszSalt, pData);
     195
     196    pfnCryptR = (PFNCRYPTR)RTLdrGetSystemSymbol("libcrypt.so", "crypt_r");
     197    if (!pfnCryptR)
     198        pfnCryptR = (PFNCRYPTR)RTLdrGetSystemSymbol("libxcrypt.so", "crypt_r");
     199    if (pfnCryptR)
     200    {
     201        s_pfnCryptR = pfnCryptR;
     202        return pfnCryptR(pszKey, pszSalt, pData);
     203    }
     204
     205    LogRel(("IPRT/RTProc: Unable to locate crypt_r!\n"));
     206    return NULL;
     207}
     208#endif /* IPRT_WITH_DYNAMIC_CRYPT_R */
    167209
    168210
     
    313355    {
    314356# if defined(RT_OS_LINUX) || defined(RT_OS_OS2)
    315         struct crypt_data CryptData;
    316         RT_ZERO(CryptData);
    317         char *pszEncPasswd = crypt_r(pszPasswd, pPwd->pw_passwd, &CryptData);
    318         rc = pszEncPasswd && !strcmp(pszEncPasswd, pPwd->pw_passwd) ? VINF_SUCCESS : VERR_AUTHENTICATION_FAILURE;
    319         RTMemWipeThoroughly(&CryptData, sizeof(CryptData), 3);
     357#  ifdef IPRT_WITH_DYNAMIC_CRYPT_R
     358        size_t const       cbCryptData = RT_MAX(sizeof(struct crypt_data) * 2, _256K);
     359#  else
     360        size_t const       cbCryptData = sizeof(struct crypt_data);
     361#  endif
     362        struct crypt_data *pCryptData  = (struct crypt_data *)RTMemTmpAllocZ(cbCryptData);
     363        if (pCryptData)
     364        {
     365#  ifdef IPRT_WITH_DYNAMIC_CRYPT_R
     366            char *pszEncPasswd = rtProcDynamicCryptR(pszPasswd, pPwd->pw_passwd, pCryptData);
     367#  else
     368            char *pszEncPasswd = crypt_r(pszPasswd, pPwd->pw_passwd, pCryptData);
     369#  endif
     370            rc = pszEncPasswd && !strcmp(pszEncPasswd, pPwd->pw_passwd) ? VINF_SUCCESS : VERR_AUTHENTICATION_FAILURE;
     371            RTMemWipeThoroughly(pCryptData, cbCryptData, 3);
     372            RTMemTmpFree(pCryptData);
     373        }
     374        else
     375            rc = VERR_NO_TMP_MEMORY;
    320376# else
    321377        char *pszEncPasswd = crypt(pszPasswd, pPwd->pw_passwd);
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette