tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

lowhash_vector.c (5449B)


      1 /*
      2 * loader.c - load platform dependent DSO containing freebl implementation.
      3 *
      4 * This Source Code Form is subject to the terms of the Mozilla Public
      5 * License, v. 2.0. If a copy of the MPL was not distributed with this
      6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      7 
      8 #define _GNU_SOURCE 1
      9 #include "loader.h"
     10 #include "prmem.h"
     11 #include "prerror.h"
     12 #include "prinit.h"
     13 #include "prenv.h"
     14 #include "blname.c"
     15 
     16 #include "prio.h"
     17 #include "prprf.h"
     18 #include <stdio.h>
     19 #include "prsystem.h"
     20 #include "nsslowhash.h"
     21 #include <dlfcn.h>
     22 #include "pratom.h"
     23 
     24 static PRLibrary *blLib;
     25 
     26 #define LSB(x) ((x)&0xff)
     27 #define MSB(x) ((x) >> 8)
     28 
     29 static const NSSLOWVector *vector;
     30 static const char *libraryName = NULL;
     31 
     32 /* pretty much only glibc uses this, make sure we don't have any depenencies
     33 * on nspr.. */
     34 #undef PORT_Alloc
     35 #undef PORT_Free
     36 #define PORT_Alloc malloc
     37 #define PR_Malloc malloc
     38 #define PORT_Free free
     39 #define PR_Free free
     40 #define PR_GetDirectorySeparator() '/'
     41 #define PR_LoadLibraryWithFlags(libspec, flags) \
     42    (PRLibrary *)dlopen(libSpec.value.pathname, RTLD_NOW | RTLD_LOCAL)
     43 #define PR_GetLibraryFilePathname(name, addr) \
     44    freebl_lowhash_getLibraryFilePath(addr)
     45 
     46 static char *
     47 freebl_lowhash_getLibraryFilePath(void *addr)
     48 {
     49    Dl_info dli;
     50    if (dladdr(addr, &dli) == 0) {
     51        return NULL;
     52    }
     53    return strdup(dli.dli_fname);
     54 }
     55 
     56 /*
     57 * The PR_LoadLibraryWithFlags call above defines this variable away, so we
     58 * don't need it..
     59 */
     60 #ifdef nodef
     61 static const char *NameOfThisSharedLib =
     62    SHLIB_PREFIX "freebl" SHLIB_VERSION "." SHLIB_SUFFIX;
     63 #endif
     64 
     65 #include "genload.c"
     66 
     67 /* This function must be run only once. */
     68 /*  determine if hybrid platform, then actually load the DSO. */
     69 static PRStatus
     70 freebl_LoadDSO(void)
     71 {
     72    PRLibrary *handle;
     73    const char *name = getLibName();
     74 
     75    if (!name) {
     76        /*PR_SetError(PR_LOAD_LIBRARY_ERROR,0); */
     77        return PR_FAILURE;
     78    }
     79    handle = loader_LoadLibrary(name);
     80    if (handle) {
     81        void *address = dlsym(handle, "NSSLOW_GetVector");
     82        if (address) {
     83            NSSLOWGetVectorFn *getVector = (NSSLOWGetVectorFn *)address;
     84            const NSSLOWVector *dsoVector = getVector();
     85            if (dsoVector) {
     86                unsigned short dsoVersion = dsoVector->version;
     87                unsigned short myVersion = NSSLOW_VERSION;
     88                if (MSB(dsoVersion) == MSB(myVersion) &&
     89                    LSB(dsoVersion) >= LSB(myVersion) &&
     90                    dsoVector->length >= sizeof(NSSLOWVector)) {
     91                    vector = dsoVector;
     92                    libraryName = name;
     93                    blLib = handle;
     94                    return PR_SUCCESS;
     95                }
     96            }
     97        }
     98        (void)dlclose(handle);
     99    }
    100    return PR_FAILURE;
    101 }
    102 
    103 static PRCallOnceType loadFreeBLOnce;
    104 
    105 static void
    106 freebl_RunLoaderOnce(void)
    107 {
    108    /* Don't have NSPR, so can use the real PR_CallOnce, implement a stripped
    109     * down version. */
    110    if (loadFreeBLOnce.initialized) {
    111        return;
    112    }
    113    if (__sync_lock_test_and_set(&loadFreeBLOnce.inProgress, 1) == 0) {
    114        loadFreeBLOnce.status = freebl_LoadDSO();
    115        loadFreeBLOnce.initialized = 1;
    116    } else {
    117        /* shouldn't have a lot of takers on the else clause, which is good
    118         * since we don't have condition variables yet.
    119         * 'initialized' only ever gets set (not cleared) so we don't
    120         * need the traditional locks. */
    121        while (!loadFreeBLOnce.initialized) {
    122            sleep(1); /* don't have condition variables, just give up the CPU */
    123        }
    124    }
    125 }
    126 
    127 static const NSSLOWVector *
    128 freebl_InitVector(void)
    129 {
    130    if (!vector) {
    131        freebl_RunLoaderOnce();
    132    }
    133    return vector;
    134 }
    135 
    136 const FREEBLVector *
    137 FREEBL_GetVector(void)
    138 {
    139    if (freebl_InitVector()) {
    140        return (vector->p_FREEBL_GetVector)();
    141    }
    142    return NULL;
    143 }
    144 
    145 NSSLOWInitContext *
    146 NSSLOW_Init(void)
    147 {
    148    if (freebl_InitVector()) {
    149        return (vector->p_NSSLOW_Init)();
    150    }
    151    return NULL;
    152 }
    153 
    154 void
    155 NSSLOW_Shutdown(NSSLOWInitContext *context)
    156 {
    157    if (freebl_InitVector()) {
    158        (vector->p_NSSLOW_Shutdown)(context);
    159    }
    160 }
    161 
    162 void
    163 NSSLOW_Reset(NSSLOWInitContext *context)
    164 {
    165    if (freebl_InitVector()) {
    166        (vector->p_NSSLOW_Reset)(context);
    167    }
    168 }
    169 
    170 NSSLOWHASHContext *
    171 NSSLOWHASH_NewContext(
    172    NSSLOWInitContext *initContext,
    173    HASH_HashType hashType)
    174 {
    175    if (freebl_InitVector()) {
    176        return (vector->p_NSSLOWHASH_NewContext)(initContext, hashType);
    177    }
    178    return NULL;
    179 }
    180 
    181 void
    182 NSSLOWHASH_Begin(NSSLOWHASHContext *context)
    183 {
    184    if (freebl_InitVector()) {
    185        (vector->p_NSSLOWHASH_Begin)(context);
    186    }
    187 }
    188 
    189 void
    190 NSSLOWHASH_Update(NSSLOWHASHContext *context,
    191                  const unsigned char *buf,
    192                  unsigned int len)
    193 {
    194    if (freebl_InitVector()) {
    195        (vector->p_NSSLOWHASH_Update)(context, buf, len);
    196    }
    197 }
    198 
    199 void
    200 NSSLOWHASH_End(NSSLOWHASHContext *context,
    201               unsigned char *buf,
    202               unsigned int *ret, unsigned int len)
    203 {
    204    if (freebl_InitVector()) {
    205        (vector->p_NSSLOWHASH_End)(context, buf, ret, len);
    206    }
    207 }
    208 
    209 void
    210 NSSLOWHASH_Destroy(NSSLOWHASHContext *context)
    211 {
    212    if (freebl_InitVector()) {
    213        (vector->p_NSSLOWHASH_Destroy)(context);
    214    }
    215 }
    216 
    217 unsigned int
    218 NSSLOWHASH_Length(NSSLOWHASHContext *context)
    219 {
    220    if (freebl_InitVector()) {
    221        return (vector->p_NSSLOWHASH_Length)(context);
    222    }
    223    return -1;
    224 }