tor-browser

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

user_environment.c (7730B)


      1 /*-
      2 * Copyright (c) 2009-2010 Brad Penoff
      3 * Copyright (c) 2009-2010 Humaira Kamal
      4 * Copyright (c) 2011-2012 Irene Ruengeler
      5 * Copyright (c) 2011-2012 Michael Tuexen
      6 *
      7 * All rights reserved.
      8 *
      9 * Redistribution and use in source and binary forms, with or without
     10 * modification, are permitted provided that the following conditions
     11 * are met:
     12 * 1. Redistributions of source code must retain the above copyright
     13 *    notice, this list of conditions and the following disclaimer.
     14 * 2. Redistributions in binary form must reproduce the above copyright
     15 *    notice, this list of conditions and the following disclaimer in the
     16 *    documentation and/or other materials provided with the distribution.
     17 *
     18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     28 * SUCH DAMAGE.
     29 */
     30 
     31 /* __Userspace__ */
     32 
     33 #if defined(_WIN32)
     34 #if !defined(_CRT_RAND_S) && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
     35 #define _CRT_RAND_S
     36 #endif
     37 #else
     38 #include <stdint.h>
     39 #include <netinet/sctp_os_userspace.h>
     40 #endif
     41 #ifdef INVARIANTS
     42 #include <netinet/sctp_pcb.h>
     43 #endif
     44 #include <user_environment.h>
     45 #include <sys/types.h>
     46 /* #include <sys/param.h> defines MIN */
     47 #if !defined(MIN)
     48 #define MIN(arg1,arg2) ((arg1) < (arg2) ? (arg1) : (arg2))
     49 #endif
     50 
     51 #define uHZ 1000
     52 
     53 /* See user_include/user_environment.h for comments about these variables */
     54 int maxsockets = 25600;
     55 int hz = uHZ;
     56 int ip_defttl = 64;
     57 int ipport_firstauto = 49152, ipport_lastauto = 65535;
     58 int nmbclusters = 65536;
     59 
     60 /* Source ip_output.c. extern'd in ip_var.h */
     61 u_short ip_id = 0; /*__Userspace__ TODO Should it be initialized to zero? */
     62 
     63 /* used in user_include/user_atomic.h in order to make the operations
     64 * defined there truly atomic
     65 */
     66 userland_mutex_t atomic_mtx;
     67 
     68 /* If the entropy device is not loaded, make a token effort to
     69 * provide _some_ kind of randomness. This should only be used
     70 * inside other RNG's, like arc4random(9).
     71 */
     72 #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
     73 #include <string.h>
     74 
     75 void
     76 init_random(void)
     77 {
     78 return;
     79 }
     80 
     81 void
     82 read_random(void *buf, size_t size)
     83 {
     84 memset(buf, 'A', size);
     85 return;
     86 }
     87 
     88 void
     89 finish_random(void)
     90 {
     91 return;
     92 }
     93 /* This define can be used to optionally use OpenSSL's random number utility,
     94 * which is capable of bypassing the chromium sandbox which normally would
     95 * prevent opening files, including /dev/urandom.
     96 */
     97 #elif defined(SCTP_USE_OPENSSL_RAND)
     98 #include <openssl/rand.h>
     99 
    100 /* Requiring BoringSSL because it guarantees that RAND_bytes will succeed. */
    101 #ifndef OPENSSL_IS_BORINGSSL
    102 #error Only BoringSSL is supported with SCTP_USE_OPENSSL_RAND.
    103 #endif
    104 
    105 void
    106 init_random(void)
    107 {
    108 return;
    109 }
    110 
    111 void
    112 read_random(void *buf, size_t size)
    113 {
    114 RAND_bytes((uint8_t *)buf, size);
    115 return;
    116 }
    117 
    118 void
    119 finish_random(void)
    120 {
    121 return;
    122 }
    123 #elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) || defined(__Bitrig__)
    124 #include <stdlib.h>
    125 
    126 void
    127 init_random(void)
    128 {
    129 return;
    130 }
    131 
    132 void
    133 read_random(void *buf, size_t size)
    134 {
    135 arc4random_buf(buf, size);
    136 return;
    137 }
    138 
    139 void
    140 finish_random(void)
    141 {
    142 return;
    143 }
    144 #elif defined(_WIN32)
    145 #include <stdlib.h>
    146 
    147 void
    148 init_random(void)
    149 {
    150 return;
    151 }
    152 
    153 void
    154 read_random(void *buf, size_t size)
    155 {
    156 unsigned int randval;
    157 size_t position, remaining;
    158 
    159 position = 0;
    160 while (position < size) {
    161 	if (rand_s(&randval) == 0) {
    162 		remaining = MIN(size - position, sizeof(unsigned int));
    163 		memcpy((char *)buf + position, &randval, remaining);
    164 		position += sizeof(unsigned int);
    165 	}
    166 }
    167 return;
    168 }
    169 
    170 void
    171 finish_random(void)
    172 {
    173 return;
    174 }
    175 #elif (defined(__ANDROID__) && (__ANDROID_API__ < 28)) || defined(__QNX__) || defined(__EMSCRIPTEN__)
    176 #include <fcntl.h>
    177 
    178 static int fd = -1;
    179 
    180 void
    181 init_random(void)
    182 {
    183 fd = open("/dev/urandom", O_RDONLY);
    184 return;
    185 }
    186 
    187 void
    188 read_random(void *buf, size_t size)
    189 {
    190 size_t position;
    191 ssize_t n;
    192 
    193 position = 0;
    194 while (position < size) {
    195 	n = read(fd, (char *)buf + position, size - position);
    196 	if (n > 0) {
    197 		position += n;
    198 	}
    199 }
    200 return;
    201 }
    202 
    203 void
    204 finish_random(void)
    205 {
    206 close(fd);
    207 return;
    208 }
    209 #elif defined(__ANDROID__) && (__ANDROID_API__ >= 28)
    210 #include <sys/random.h>
    211 
    212 void
    213 init_random(void)
    214 {
    215 return;
    216 }
    217 
    218 void
    219 read_random(void *buf, size_t size)
    220 {
    221 size_t position;
    222 ssize_t n;
    223 
    224 position = 0;
    225 while (position < size) {
    226 	n = getrandom((char *)buf + position, size - position, 0);
    227 	if (n > 0) {
    228 		position += n;
    229 	}
    230 }
    231 return;
    232 }
    233 
    234 void
    235 finish_random(void)
    236 {
    237 return;
    238 }
    239 #elif defined(__linux__)
    240 #include <fcntl.h>
    241 #include <unistd.h>
    242 #include <sys/syscall.h>
    243 
    244 #if defined(__has_feature)
    245 #if __has_feature(memory_sanitizer)
    246 void __msan_unpoison(void *, size_t);
    247 #endif
    248 #endif
    249 
    250 #ifdef __NR_getrandom
    251 #if !defined(GRND_NONBLOCK)
    252 #define GRND_NONBLOCK 1
    253 #endif
    254 static int getrandom_available = 0;
    255 #endif
    256 static int fd = -1;
    257 
    258 void
    259 init_random(void)
    260 {
    261 #ifdef __NR_getrandom
    262 char dummy;
    263 ssize_t n = syscall(__NR_getrandom, &dummy, sizeof(dummy), GRND_NONBLOCK);
    264 if (n > 0 || errno == EINTR || errno == EAGAIN) {
    265 	/* Either getrandom succeeded, was interrupted or is waiting for entropy;
    266 	 * all of which mean the syscall is available.
    267 	 */
    268 	getrandom_available = 1;
    269 } else {
    270 #ifdef INVARIANTS
    271 	if (errno != ENOSYS) {
    272 		panic("getrandom syscall returned unexpected error: %d", errno);
    273 	}
    274 #endif
    275 	/* If the syscall isn't available, fall back to /dev/urandom. */
    276 #endif
    277 	fd = open("/dev/urandom", O_RDONLY);
    278 #ifdef __NR_getrandom
    279 }
    280 #endif
    281 return;
    282 }
    283 
    284 void
    285 read_random(void *buf, size_t size)
    286 {
    287 size_t position;
    288 ssize_t n;
    289 
    290 position = 0;
    291 while (position < size) {
    292 #ifdef __NR_getrandom
    293 	if (getrandom_available) {
    294 		/* Using syscall directly because getrandom isn't present in glibc < 2.25.
    295 		 */
    296 		n = syscall(__NR_getrandom, (char *)buf + position, size - position, 0);
    297 		if (n > 0) {
    298 #if defined(__has_feature)
    299 #if __has_feature(memory_sanitizer)
    300 			/* Need to do this because MSan doesn't realize that syscall has
    301 			 * initialized the output buffer.
    302 			 */
    303 			__msan_unpoison(buf + position, n);
    304 #endif
    305 #endif
    306 			position += n;
    307 		} else if (errno != EINTR && errno != EAGAIN) {
    308 #ifdef INVARIANTS
    309 			panic("getrandom syscall returned unexpected error: %d", errno);
    310 #endif
    311 		}
    312 	} else
    313 #endif /* __NR_getrandom */
    314 	{
    315 		n = read(fd, (char *)buf + position, size - position);
    316 		if (n > 0) {
    317 			position += n;
    318 		}
    319 	}
    320 }
    321 return;
    322 }
    323 
    324 void
    325 finish_random(void)
    326 {
    327 if (fd != -1) {
    328 	close(fd);
    329 }
    330 return;
    331 }
    332 #elif defined(__Fuchsia__)
    333 #include <zircon/syscalls.h>
    334 
    335 void
    336 init_random(void)
    337 {
    338 return;
    339 }
    340 
    341 void
    342 read_random(void *buf, size_t size)
    343 {
    344 zx_cprng_draw(buf, size);
    345 return;
    346 }
    347 
    348 void
    349 finish_random(void)
    350 {
    351 return;
    352 }
    353 #elif defined(__native_client__)
    354 #include <nacl/nacl_random.h>
    355 
    356 void
    357 init_random(void)
    358 {
    359 return;
    360 }
    361 
    362 void
    363 read_random(void *buf, size_t size)
    364 {
    365 size_t position;
    366 size_t n;
    367 
    368 position = 0;
    369 while (position < size) {
    370 	if (nacl_secure_random((char *)buf + position, size - position, &n) == 0) {
    371 		position += n;
    372 	}
    373 }
    374 return;
    375 }
    376 
    377 void
    378 finish_random(void)
    379 {
    380 return;
    381 }
    382 #else
    383 #error "Unknown platform. Please provide platform specific RNG."
    384 #endif