sys_getrandom.c (6469bdcdb6a5968dc7edfcfb495d427b4bfdb3dd) | sys_getrandom.c (86def3dcd66af169aac0c6ff91dd94a98369cc89) |
---|---|
1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2018 Conrad Meyer <cem@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 24 unchanged lines hidden (view full) --- 33#include <sys/errno.h> 34#include <sys/limits.h> 35#include <sys/proc.h> 36#include <sys/random.h> 37#include <sys/sysproto.h> 38#include <sys/systm.h> 39#include <sys/uio.h> 40 | 1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2018 Conrad Meyer <cem@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 24 unchanged lines hidden (view full) --- 33#include <sys/errno.h> 34#include <sys/limits.h> 35#include <sys/proc.h> 36#include <sys/random.h> 37#include <sys/sysproto.h> 38#include <sys/systm.h> 39#include <sys/uio.h> 40 |
41#define GRND_VALIDFLAGS (GRND_NONBLOCK | GRND_RANDOM) | 41#define GRND_VALIDFLAGS (GRND_NONBLOCK | GRND_RANDOM | GRND_INSECURE) |
42 43/* 44 * random_read_uio(9) returns EWOULDBLOCK if a nonblocking request would block, 45 * but the Linux API name is EAGAIN. On FreeBSD, they have the same numeric 46 * value for now. 47 */ 48CTASSERT(EWOULDBLOCK == EAGAIN); 49 --- 5 unchanged lines hidden (view full) --- 55 struct iovec aiov; 56 int error; 57 58 if ((flags & ~GRND_VALIDFLAGS) != 0) 59 return (EINVAL); 60 if (buflen > IOSIZE_MAX) 61 return (EINVAL); 62 | 42 43/* 44 * random_read_uio(9) returns EWOULDBLOCK if a nonblocking request would block, 45 * but the Linux API name is EAGAIN. On FreeBSD, they have the same numeric 46 * value for now. 47 */ 48CTASSERT(EWOULDBLOCK == EAGAIN); 49 --- 5 unchanged lines hidden (view full) --- 55 struct iovec aiov; 56 int error; 57 58 if ((flags & ~GRND_VALIDFLAGS) != 0) 59 return (EINVAL); 60 if (buflen > IOSIZE_MAX) 61 return (EINVAL); 62 |
63 /* 64 * Linux compatibility: We have two choices for handling Linux's 65 * GRND_INSECURE. 66 * 67 * 1. We could ignore it completely (like GRND_RANDOM). However, this 68 * might produce the surprising result of GRND_INSECURE requests 69 * blocking, when the Linux API does not block. 70 * 71 * 2. Alternatively, we could treat GRND_INSECURE requests as requests 72 * for GRND_NONBLOCk. Here, the surprising result for Linux programs 73 * is that invocations with unseeded random(4) will produce EAGAIN, 74 * rather than garbage. 75 * 76 * Honoring the flag in the way Linux does seems fraught. If we 77 * actually use the output of a random(4) implementation prior to 78 * seeding, we leak some entropy about the initial seed to attackers. 79 * This seems unacceptable -- it defeats the purpose of blocking on 80 * initial seeding. 81 * 82 * Secondary to that concern, before seeding we may have arbitrarily 83 * little entropy collected; producing output from zero or a handful of 84 * entropy bits does not seem particularly useful to userspace. 85 * 86 * If userspace can accept garbage, insecure non-random bytes, they can 87 * create their own insecure garbage with srandom(time(NULL)) or 88 * similar. Asking the kernel to produce it from the secure 89 * getrandom(2) API seems inane. 90 * 91 * We elect to emulate GRND_INSECURE as an alternative spelling of 92 * GRND_NONBLOCK (2). 93 */ 94 if ((flags & GRND_INSECURE) != 0) 95 flags |= GRND_NONBLOCK; 96 |
|
63 if (buflen == 0) { 64 td->td_retval[0] = 0; 65 return (0); 66 } 67 68 aiov.iov_base = user_buf; 69 aiov.iov_len = buflen; 70 auio.uio_iov = &aiov; --- 26 unchanged lines hidden --- | 97 if (buflen == 0) { 98 td->td_retval[0] = 0; 99 return (0); 100 } 101 102 aiov.iov_base = user_buf; 103 aiov.iov_len = buflen; 104 auio.uio_iov = &aiov; --- 26 unchanged lines hidden --- |