16209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes/* $OpenBSD: arc4random_linux.h,v 1.7 2014/07/20 20:51:13 bcook Exp $ */ 26209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes 36209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes/* 46209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes * Copyright (c) 1996, David Mazieres <dm@uun.org> 56209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes * Copyright (c) 2008, Damien Miller <djm@openbsd.org> 66209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes * Copyright (c) 2013, Markus Friedl <markus@openbsd.org> 76209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes * 86209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes * Permission to use, copy, modify, and distribute this software for any 96209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes * purpose with or without fee is hereby granted, provided that the above 106209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes * copyright notice and this permission notice appear in all copies. 116209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes * 126209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 136209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 146209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 156209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 166209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 176209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 186209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 196209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes */ 206209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes 216209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes/* 226209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes * Stub functions for portability. 236209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes */ 246209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes 256209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes#include <sys/mman.h> 266209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes 276209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes#include <pthread.h> 286209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes#include <signal.h> 296209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes 306209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes// Android gets these from "thread_private.h". 316209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes#include "thread_private.h" 326209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes//static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; 336209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes//#define _ARC4_LOCK() pthread_mutex_lock(&arc4random_mtx) 346209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes//#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx) 356209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes 366209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes#ifdef __GLIBC__ 376209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughesextern void *__dso_handle; 386209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughesextern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *); 396209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes#define _ARC4_ATFORK(f) __register_atfork(NULL, NULL, (f), __dso_handle) 406209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes#else 416209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f)) 426209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes#endif 436209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes 446209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughesstatic inline void 456209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes_getentropy_fail(void) 466209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes{ 476209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes raise(SIGKILL); 486209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes} 496209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes 506209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughesstatic volatile sig_atomic_t _rs_forked; 516209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes 526209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughesstatic inline void 536209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes_rs_forkhandler(void) 546209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes{ 556209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes _rs_forked = 1; 566209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes} 576209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes 586209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughesstatic inline void 596209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes_rs_forkdetect(void) 606209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes{ 616209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes static pid_t _rs_pid = 0; 626209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes pid_t pid = getpid(); 636209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes 646209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes if (_rs_pid == 0 || _rs_pid != pid || _rs_forked) { 656209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes _rs_pid = pid; 666209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes _rs_forked = 0; 676209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes if (rs) 686209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes memset(rs, 0, sizeof(*rs)); 696209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes } 706209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes} 716209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes 726209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughesstatic inline int 736209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes_rs_allocate(struct _rs **rsp, struct _rsx **rsxp) 746209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes{ 756209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE, 766209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) 776209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes return (-1); 786209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes 796209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE, 806209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) { 816209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes munmap(*rsxp, sizeof(**rsxp)); 826209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes return (-1); 836209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes } 846209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes 856209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes _ARC4_ATFORK(_rs_forkhandler); 866209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes return (0); 876209c81d40e2b4e129a28bda3259150d79d507e8Elliott Hughes} 88