1227522Sdas/*- 2227522Sdas * Copyright (c) 2011 David Schultz 3227522Sdas * All rights reserved. 4227522Sdas * 5227522Sdas * Redistribution and use in source and binary forms, with or without 6227522Sdas * modification, are permitted provided that the following conditions 7227522Sdas * are met: 8227522Sdas * 1. Redistributions of source code must retain the above copyright 9227522Sdas * notice, this list of conditions and the following disclaimer. 10227522Sdas * 2. Redistributions in binary form must reproduce the above copyright 11227522Sdas * notice, this list of conditions and the following disclaimer in the 12227522Sdas * documentation and/or other materials provided with the distribution. 13227522Sdas * 14227522Sdas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15227522Sdas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16227522Sdas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17227522Sdas * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18227522Sdas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19227522Sdas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20227522Sdas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21227522Sdas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22227522Sdas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23227522Sdas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24227522Sdas * SUCH DAMAGE. 25227522Sdas */ 26227522Sdas 27227522Sdas#include <sys/cdefs.h> 28227522Sdas__FBSDID("$FreeBSD$"); 29227522Sdas 30274581Sngie#include <sys/types.h> 31227522Sdas#include <sys/mman.h> 32227522Sdas#include <sys/wait.h> 33290571Sngie#include <errno.h> 34227522Sdas#include <stdio.h> 35227522Sdas#include <stdlib.h> 36227522Sdas#include <string.h> 37227522Sdas#include <unistd.h> 38290571Sngie 39274581Sngie#include <atf-c.h> 40227522Sdas 41227522Sdas/* 42227522Sdas * BUFSIZE is the number of bytes of rc4 output to compare. The probability 43227522Sdas * that this test fails spuriously is 2**(-BUFSIZE * 8). 44227522Sdas */ 45227522Sdas#define BUFSIZE 8 46227522Sdas 47227522Sdas/* 48227522Sdas * Test whether arc4random_buf() returns the same sequence of bytes in both 49227522Sdas * parent and child processes. (Hint: It shouldn't.) 50227522Sdas */ 51274581SngieATF_TC_WITHOUT_HEAD(test_arc4random); 52274581SngieATF_TC_BODY(test_arc4random, tc) 53274581Sngie{ 54227522Sdas struct shared_page { 55227522Sdas char parentbuf[BUFSIZE]; 56227522Sdas char childbuf[BUFSIZE]; 57227522Sdas } *page; 58227522Sdas pid_t pid; 59227522Sdas char c; 60227522Sdas 61227522Sdas page = mmap(NULL, sizeof(struct shared_page), PROT_READ | PROT_WRITE, 62227522Sdas MAP_ANON | MAP_SHARED, -1, 0); 63290571Sngie ATF_REQUIRE_MSG(page != MAP_FAILED, "mmap failed; errno=%d", errno); 64227522Sdas 65227522Sdas arc4random_buf(&c, 1); 66227522Sdas 67227522Sdas pid = fork(); 68274581Sngie ATF_REQUIRE(0 <= pid); 69227522Sdas if (pid == 0) { 70227522Sdas /* child */ 71227522Sdas arc4random_buf(page->childbuf, BUFSIZE); 72227522Sdas exit(0); 73227522Sdas } else { 74227522Sdas /* parent */ 75227522Sdas int status; 76227522Sdas arc4random_buf(page->parentbuf, BUFSIZE); 77227522Sdas wait(&status); 78227522Sdas } 79274581Sngie ATF_CHECK_MSG(memcmp(page->parentbuf, page->childbuf, BUFSIZE) != 0, 80274581Sngie "sequences are the same"); 81274581Sngie} 82227522Sdas 83274581SngieATF_TP_ADD_TCS(tp) 84274581Sngie{ 85274581Sngie 86274581Sngie ATF_TP_ADD_TC(tp, test_arc4random); 87274581Sngie 88274581Sngie return (atf_no_error()); 89227522Sdas} 90