All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH -v5] random: introduce getrandom(2) system call
@ 2014-07-24 14:31 Theodore Ts'o
  2014-07-24 15:18 ` Henrique de Moraes Holschuh
       [not found] ` <1406212287-9855-1-git-send-email-tytso-3s7WtUTddSA@public.gmane.org>
  0 siblings, 2 replies; 15+ messages in thread
From: Theodore Ts'o @ 2014-07-24 14:31 UTC (permalink / raw)
  To: Linux Kernel Developers List; +Cc: linux-api, linux-crypto, Theodore Ts'o

The getrandom(2) system call was requested by the LibreSSL Portable
developers.  It is analoguous to the getentropy(2) system call in
OpenBSD.

The rationale of this system call is to provide resiliance against
file descriptor exhaustion attacks, where the attacker consumes all
available file descriptors, forcing the use of the fallback code where
/dev/[u]random is not available.  Since the fallback code is often not
well-tested, it is better to eliminate this potential failure mode
entirely.

The other feature provided by this new system call is the ability to
request randomness from the /dev/urandom entropy pool, but to block
until at least 128 bits of entropy has been accumulated in the
/dev/urandom entropy pool.  Historically, the emphasis in the
/dev/urandom development has been to ensure that urandom pool is
initialized as quickly as possible after system boot, and preferably
before the init scripts start execution.

This is because changing /dev/urandom reads to block represents an
interface change that could potentially break userspace which is not
acceptable.  In practice, on most x86 desktop and server systems, in
general the entropy pool can be initialized before it is needed (and
in modern kernels, we will printk a warning message if not).  However,
on an embedded system, this may not be the case.  And so with this new
interface, we can provide the functionality of blocking until the
urandom pool has been initialized.  Any userspace program which uses
this new functionality must take care to assure that if it is used
during the boot process, that it will not cause the init scripts or
other portions of the system startup to hang indefinitely.

SYNOPSIS
	#include <linux/random.h>

	int getrandom(void *buf, size_t buflen, unsigned int flags);

DESCRIPTION
	The system call getrandom() fills the buffer pointed to by buf
	with up to buflen random bytes which can be used to seed user
	space random number generators (i.e., DRBG's) or for other
	cryptographic uses.  It should not be used for Monte Carlo
	simulations or other programs/algorithms which are doing
	probabilistic sampling.

	If the GRND_RANDOM flags bit is set, then draw from the
	/dev/random pool instead of the /dev/urandom pool.  The
	/dev/random pool is limited based on the entropy that can be
	obtained from environmental noise, so if there is insufficient
	entropy, the requested number of bytes may not be returned.
	If there is no entropy available at all, getrandom(2) will
	either block, or return an error with errno set to EAGAIN if
	the GRND_NONBLOCK bit is set in flags.

	If the GRND_RANDOM bit is not set, then the /dev/urandom pool
	will be used.  Unlike using read(2) to fetch data from
	/dev/urandom, if the urandom pool has not been sufficiently
	initialized, getrandom(2) will block (or return -1 with the
	errno set to EAGAIN if the GRND_NONBLOCK bit is set in flags).

	The getentropy(2) system call in OpenBSD can be emulated using
	the following function:

            int getentropy(void *buf, size_t buflen)
            {
                    int     ret;

                    if (buflen > 256)
                            goto failure;
                    ret = getrandom(buf, buflen, 0);
                    if (ret < 0)
                            return ret;
                    if (ret == buflen)
                            return 0;
            failure:
                    errno = EIO;
                    return -1;
            }

RETURN VALUE
       On success, the number of bytes that was filled in the buf is
       returned.  This may not be all the bytes requested by the
       caller via buflen if insufficient entropy was present in the
       /dev/random pool, or if the system call was interrupted by a
       signal.

       On error, -1 is returned, and errno is set appropriately.

ERRORS
	EINVAL		An invalid flag was passed to getrandom(2)

	EFAULT		buf is outside the accessible address space.

	EAGAIN		The requested entropy was not available, and
			getentropy(2) would have blocked if GRND_BLOCK flag
			was set.

	EINTR		While blocked waiting for entropy, the call was
			interrupted by a signal handler; see the description
			of how interrupted read(2) calls on "slow" devices
			are handled with and without the SA_RESTART flag
			in the signal(7) man page.

NOTES
	For small requests (buflen <= 256) getrandom(2) will not
	return EINTR when reading from the urandom pool once the
	entropy pool has been initialized, and it will return all of
	the bytes that have been requested.  This is the recommended
	way to use getrandom(2), and is designed for compatibility
	with OpenBSD's getentropy() system call.

	However, if you are using GRND_RANDOM, then getrandom(2) may
	block until the entropy accounting determines that sufficient
	environmental noise has been gathered such that getrandom(2)
	will be operating as a NRBG instead of a DRBG for those people
	who are working in the NIST SP 800-90 regime.  Since it may
	block for a long time, these guarantees do *not* apply.  The
	user may want to interrupt a hanging process using a signal,
	so blocking until all of the requested bytes are returned
	would be unfriendly.

	For this reason, the user of getrandom(2) MUST always check
	the return value, in case it returns some error, or if fewer
	bytes than requested was returned.  In the case of
	!GRND_RANDOM and small request, the latter should never
	happen, but the careful userspace code (and all crypto code
	should be careful) should check for this anyway!

	Finally, unless you are doing long-term key generation (and
	perhaps not even then), you probably shouldn't be using
	GRND_RANDOM.  The cryptographic algorithms used for
	/dev/urandom are quite conservative, and so should be
	sufficient for all purposes.  The disadvantage of GRND_RANDOM
	is that it can block, and the increased complexity required to
	deal with partially fulfilled getrandom(2) requests.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Zach Brown <zab@zabbo.net>
---
Changelog:

v5: Change syscall numbers to avoid conflict with seccomp, and so that
    people who are testing linux-next will (hopefully) won't see
    different syscall numbers when things get merged mainline

    More man page tweaks.

v4: Use a wait queue and wait_event() instead of a completion handler

    More fine tuning of the commit description and man page

v3: Eliminate potential short reads and EINTR returns when requesting
    small amounts of entropy from urandom (once the urandom pool is
    initialized).   See the NOTES section in the suggested man page for
    a more in-depth discussion of the issues involved.

v2: Statically declare the completion structure

    Check for and reject unknown flags


 arch/x86/syscalls/syscall_32.tbl  |  1 +
 arch/x86/syscalls/syscall_64.tbl  |  1 +
 drivers/char/random.c             | 40 ++++++++++++++++++++++++++++++++++++---
 include/linux/syscalls.h          |  3 +++
 include/uapi/asm-generic/unistd.h |  4 +++-
 include/uapi/linux/random.h       |  9 +++++++++
 6 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
index d6b8679..5b46a61 100644
--- a/arch/x86/syscalls/syscall_32.tbl
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -360,3 +360,4 @@
 351	i386	sched_setattr		sys_sched_setattr
 352	i386	sched_getattr		sys_sched_getattr
 353	i386	renameat2		sys_renameat2
+355	i386	getrandom		sys_getrandom
diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl
index ec255a1..0dc4bf8 100644
--- a/arch/x86/syscalls/syscall_64.tbl
+++ b/arch/x86/syscalls/syscall_64.tbl
@@ -323,6 +323,7 @@
 314	common	sched_setattr		sys_sched_setattr
 315	common	sched_getattr		sys_sched_getattr
 316	common	renameat2		sys_renameat2
+318	common	getrandom		sys_getrandom
 
 #
 # x32-specific system call numbers start at 512 to avoid cache impact
diff --git a/drivers/char/random.c b/drivers/char/random.c
index aa22fe5..7d1682e 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -258,6 +258,8 @@
 #include <linux/kmemcheck.h>
 #include <linux/workqueue.h>
 #include <linux/irq.h>
+#include <linux/syscalls.h>
+#include <linux/completion.h>
 
 #include <asm/processor.h>
 #include <asm/uaccess.h>
@@ -404,6 +406,7 @@ static struct poolinfo {
  */
 static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
 static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
+static DECLARE_WAIT_QUEUE_HEAD(urandom_init_wait);
 static struct fasync_struct *fasync;
 
 /**********************************************************************
@@ -657,6 +660,7 @@ retry:
 		r->entropy_total = 0;
 		if (r == &nonblocking_pool) {
 			prandom_reseed_late();
+			wake_up_interruptible(&urandom_init_wait);
 			pr_notice("random: %s pool is initialized\n", r->name);
 		}
 	}
@@ -1174,13 +1178,14 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
 {
 	ssize_t ret = 0, i;
 	__u8 tmp[EXTRACT_SIZE];
+	int large_request = (nbytes > 256);
 
 	trace_extract_entropy_user(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_);
 	xfer_secondary_pool(r, nbytes);
 	nbytes = account(r, nbytes, 0, 0);
 
 	while (nbytes) {
-		if (need_resched()) {
+		if (large_request && need_resched()) {
 			if (signal_pending(current)) {
 				if (ret == 0)
 					ret = -ERESTARTSYS;
@@ -1355,7 +1360,7 @@ static int arch_random_refill(void)
 }
 
 static ssize_t
-random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+_random_read(int nonblock, char __user *buf, size_t nbytes)
 {
 	ssize_t n;
 
@@ -1379,7 +1384,7 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 		if (arch_random_refill())
 			continue;
 
-		if (file->f_flags & O_NONBLOCK)
+		if (nonblock)
 			return -EAGAIN;
 
 		wait_event_interruptible(random_read_wait,
@@ -1391,6 +1396,12 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 }
 
 static ssize_t
+random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+{
+	return _random_read(file->f_flags & O_NONBLOCK, buf, nbytes);
+}
+
+static ssize_t
 urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 {
 	int ret;
@@ -1533,6 +1544,29 @@ const struct file_operations urandom_fops = {
 	.llseek = noop_llseek,
 };
 
+SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
+		unsigned int, flags)
+{
+	if (flags & ~(GRND_NONBLOCK|GRND_RANDOM))
+		return -EINVAL;
+
+	if (count > INT_MAX)
+		count = INT_MAX;
+
+	if (flags & GRND_RANDOM)
+		return _random_read(flags & GRND_NONBLOCK, buf, count);
+
+	if (unlikely(nonblocking_pool.initialized == 0)) {
+		if (flags & GRND_NONBLOCK)
+			return -EAGAIN;
+		wait_event_interruptible(urandom_init_wait,
+					 nonblocking_pool.initialized);
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+	}
+	return urandom_read(NULL, buf, count, NULL);
+}
+
 /***************************************************************
  * Random UUID interface
  *
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index b0881a0..43324a8 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -866,4 +866,7 @@ asmlinkage long sys_process_vm_writev(pid_t pid,
 asmlinkage long sys_kcmp(pid_t pid1, pid_t pid2, int type,
 			 unsigned long idx1, unsigned long idx2);
 asmlinkage long sys_finit_module(int fd, const char __user *uargs, int flags);
+asmlinkage long sys_getrandom(char __user *buf, size_t count,
+			      unsigned int flags);
+
 #endif
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 3336406..1d104a2 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -699,9 +699,11 @@ __SYSCALL(__NR_sched_setattr, sys_sched_setattr)
 __SYSCALL(__NR_sched_getattr, sys_sched_getattr)
 #define __NR_renameat2 276
 __SYSCALL(__NR_renameat2, sys_renameat2)
+#define __NR_getrandom 278
+__SYSCALL(__NR_getrandom, sys_getrandom)
 
 #undef __NR_syscalls
-#define __NR_syscalls 277
+#define __NR_syscalls 279
 
 /*
  * All syscalls below here should go away really,
diff --git a/include/uapi/linux/random.h b/include/uapi/linux/random.h
index fff3528..3f93d16 100644
--- a/include/uapi/linux/random.h
+++ b/include/uapi/linux/random.h
@@ -40,4 +40,13 @@ struct rand_pool_info {
 	__u32	buf[0];
 };
 
+/*
+ * Flags for getrandom(2)
+ *
+ * GRND_NONBLOCK	Don't block and return EAGAIN instead
+ * GRND_RANDOM		Use the /dev/random pool instead of /dev/urandom
+ */
+#define GRND_NONBLOCK	0x0001
+#define GRND_RANDOM	0x0002
+
 #endif /* _UAPI_LINUX_RANDOM_H */
-- 
2.0.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH -v5] random: introduce getrandom(2) system call
  2014-07-24 14:31 [PATCH -v5] random: introduce getrandom(2) system call Theodore Ts'o
@ 2014-07-24 15:18 ` Henrique de Moraes Holschuh
  2014-07-24 15:21   ` Andy Lutomirski
       [not found] ` <1406212287-9855-1-git-send-email-tytso-3s7WtUTddSA@public.gmane.org>
  1 sibling, 1 reply; 15+ messages in thread
From: Henrique de Moraes Holschuh @ 2014-07-24 15:18 UTC (permalink / raw)
  To: Theodore Ts'o; +Cc: Linux Kernel Developers List, linux-api, linux-crypto

On Thu, 24 Jul 2014, Theodore Ts'o wrote:
> ERRORS
> 	EINVAL		An invalid flag was passed to getrandom(2)
> 
> 	EFAULT		buf is outside the accessible address space.
> 
> 	EAGAIN		The requested entropy was not available, and
> 			getentropy(2) would have blocked if GRND_BLOCK flag
> 			was set.
> 
> 	EINTR		While blocked waiting for entropy, the call was
> 			interrupted by a signal handler; see the description
> 			of how interrupted read(2) calls on "slow" devices
> 			are handled with and without the SA_RESTART flag
> 			in the signal(7) man page.

Should we add E<SOMETHING> to be able to deny access to GRND_RANDOM or some
future extension ?

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH -v5] random: introduce getrandom(2) system call
  2014-07-24 15:18 ` Henrique de Moraes Holschuh
@ 2014-07-24 15:21   ` Andy Lutomirski
  2014-07-24 19:02     ` Theodore Ts'o
  0 siblings, 1 reply; 15+ messages in thread
From: Andy Lutomirski @ 2014-07-24 15:21 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: Theodore Ts'o, Linux Kernel Developers List, Linux API, linux-crypto

On Thu, Jul 24, 2014 at 8:18 AM, Henrique de Moraes Holschuh
<hmh@hmh.eng.br> wrote:
> On Thu, 24 Jul 2014, Theodore Ts'o wrote:
>> ERRORS
>>       EINVAL          An invalid flag was passed to getrandom(2)
>>
>>       EFAULT          buf is outside the accessible address space.
>>
>>       EAGAIN          The requested entropy was not available, and
>>                       getentropy(2) would have blocked if GRND_BLOCK flag
>>                       was set.
>>
>>       EINTR           While blocked waiting for entropy, the call was
>>                       interrupted by a signal handler; see the description
>>                       of how interrupted read(2) calls on "slow" devices
>>                       are handled with and without the SA_RESTART flag
>>                       in the signal(7) man page.
>
> Should we add E<SOMETHING> to be able to deny access to GRND_RANDOM or some
> future extension ?

This might actually be needed sooner rather than later.  There are
programs that use containers and intentionally don't pass /dev/random
through into the container.  I know that Sandstorm does this, and I
wouldn't be surprised if other things (Docker?) do the same thing.

--Andy

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH -v5] random: introduce getrandom(2) system call
  2014-07-24 15:21   ` Andy Lutomirski
@ 2014-07-24 19:02     ` Theodore Ts'o
  2014-07-24 20:30       ` Henrique de Moraes Holschuh
  0 siblings, 1 reply; 15+ messages in thread
From: Theodore Ts'o @ 2014-07-24 19:02 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Henrique de Moraes Holschuh, Linux Kernel Developers List,
	Linux API, linux-crypto

On Thu, Jul 24, 2014 at 08:21:38AM -0700, Andy Lutomirski wrote:
> >
> > Should we add E<SOMETHING> to be able to deny access to GRND_RANDOM or some
> > future extension ?
> 
> This might actually be needed sooner rather than later.  There are
> programs that use containers and intentionally don't pass /dev/random
> through into the container.  I know that Sandstorm does this, and I
> wouldn't be surprised if other things (Docker?) do the same thing.

I wouldn't add the error to the man page until we actually modify the
kernel to add such a restriction.

However, the thought crossed my mind a while back that perhaps the
right answer is a cgroup controller which controls the rate at which a
process is allowed to drain entropy from the /dev/random pool.  This
could be set to 0, or it could be set to N bits per unit time T, and
if the process exceeded the value, it would just block or return
EAGAIN.  So instead of making it be just a binary "you have access" or
"you don't", it would actually be a kernel resource that could be
controlled just like disk bandwidth, networking bandwidth, memory, and
CPU time.

Then I decided that it was overkill, but for people who are trying to
treat containers as a way to divide up OS resources between mutually
suspicious customers in a fashion which is more efficient thatn using
VM's, maybe it is something that someone will want to implement.

      	       	  	    	 	    	- Ted

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH -v5] random: introduce getrandom(2) system call
  2014-07-24 19:02     ` Theodore Ts'o
@ 2014-07-24 20:30       ` Henrique de Moraes Holschuh
  2014-07-24 20:54         ` Andy Lutomirski
  2014-07-24 23:24         ` Theodore Ts'o
  0 siblings, 2 replies; 15+ messages in thread
From: Henrique de Moraes Holschuh @ 2014-07-24 20:30 UTC (permalink / raw)
  To: Theodore Ts'o, Andy Lutomirski, Linux Kernel Developers List,
	Linux API, linux-crypto

On Thu, 24 Jul 2014, Theodore Ts'o wrote:
> On Thu, Jul 24, 2014 at 08:21:38AM -0700, Andy Lutomirski wrote:
> > > Should we add E<SOMETHING> to be able to deny access to GRND_RANDOM or some
> > > future extension ?
> > 
> > This might actually be needed sooner rather than later.  There are
> > programs that use containers and intentionally don't pass /dev/random
> > through into the container.  I know that Sandstorm does this, and I
> > wouldn't be surprised if other things (Docker?) do the same thing.
> 
> I wouldn't add the error to the man page until we actually modify the
> kernel to add such a restriction.

By then, it might be too late.  It would be really sad to find ourselves
forced to return ENOSYS to getrandom(GRND_RANDOM) when we actually wanted to
return EPERM/EACCES.

Actually, we might not be able to do even that much: all it takes is for
someone to have the bright idea of deploying userspace code that checks for
ENOSYS only on a first "probe" getrandom() syscall without GRND_RANDOM, and
does something idiotic when it gets ENOSYS later on a
getrandom(GRND_RANDOM).  meh.  We can't even abuse the system ourselves :-)

> However, the thought crossed my mind a while back that perhaps the
> right answer is a cgroup controller which controls the rate at which a
> process is allowed to drain entropy from the /dev/random pool.  This
> could be set to 0, or it could be set to N bits per unit time T, and
> if the process exceeded the value, it would just block or return
> EAGAIN.  So instead of making it be just a binary "you have access" or

That will teach people to not have a SIGALRM on code that calls a blocking
syscall, I suppose.  Still, there is a risk it could cause so much bad
application behaviour to the point of being unusable.

> Then I decided that it was overkill, but for people who are trying to

Indeed :p

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH -v5] random: introduce getrandom(2) system call
  2014-07-24 20:30       ` Henrique de Moraes Holschuh
@ 2014-07-24 20:54         ` Andy Lutomirski
  2014-07-24 23:27           ` H. Peter Anvin
  2014-07-24 23:24         ` Theodore Ts'o
  1 sibling, 1 reply; 15+ messages in thread
From: Andy Lutomirski @ 2014-07-24 20:54 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: Theodore Ts'o, Linux Kernel Developers List, Linux API, linux-crypto

On Thu, Jul 24, 2014 at 1:30 PM, Henrique de Moraes Holschuh
<hmh@hmh.eng.br> wrote:
> On Thu, 24 Jul 2014, Theodore Ts'o wrote:
>> On Thu, Jul 24, 2014 at 08:21:38AM -0700, Andy Lutomirski wrote:
>> > > Should we add E<SOMETHING> to be able to deny access to GRND_RANDOM or some
>> > > future extension ?
>> >
>> > This might actually be needed sooner rather than later.  There are
>> > programs that use containers and intentionally don't pass /dev/random
>> > through into the container.  I know that Sandstorm does this, and I
>> > wouldn't be surprised if other things (Docker?) do the same thing.
>>
>> I wouldn't add the error to the man page until we actually modify the
>> kernel to add such a restriction.
>
> By then, it might be too late.  It would be really sad to find ourselves
> forced to return ENOSYS to getrandom(GRND_RANDOM) when we actually wanted to
> return EPERM/EACCES.
>
> Actually, we might not be able to do even that much: all it takes is for
> someone to have the bright idea of deploying userspace code that checks for
> ENOSYS only on a first "probe" getrandom() syscall without GRND_RANDOM, and
> does something idiotic when it gets ENOSYS later on a
> getrandom(GRND_RANDOM).  meh.  We can't even abuse the system ourselves :-)
>

Or that someone writes userspace code that gets -EPERM/-EACCESS on
getrandom with GRND_RANDOM and falls back to something worse than
getrandom w/o GRND_RANDOM.

--Andy

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH -v5] random: introduce getrandom(2) system call
  2014-07-24 20:30       ` Henrique de Moraes Holschuh
  2014-07-24 20:54         ` Andy Lutomirski
@ 2014-07-24 23:24         ` Theodore Ts'o
  2014-07-24 23:27           ` Andy Lutomirski
       [not found]           ` <20140724232434.GN6673-AKGzg7BKzIDYtjvyW6yDsg@public.gmane.org>
  1 sibling, 2 replies; 15+ messages in thread
From: Theodore Ts'o @ 2014-07-24 23:24 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: Andy Lutomirski, Linux Kernel Developers List, Linux API, linux-crypto

On Thu, Jul 24, 2014 at 05:30:19PM -0300, Henrique de Moraes Holschuh wrote:
> > I wouldn't add the error to the man page until we actually modify the
> > kernel to add such a restriction.
> 
> By then, it might be too late.  It would be really sad to find ourselves
> forced to return ENOSYS to getrandom(GRND_RANDOM) when we actually wanted to
> return EPERM/EACCES.

I wouldn't worry about.  The reality is that anyone using GRND_RANDOM
has to be checking for error codes anyway, and if they do something
stupid because the system call returns EPERM/EACCESS when they weren't
expecting it, again, they are much more likely to be making many other
fatal mistakes anyway.

In general, all system calls can return errno's other than the ones
documented in the man page.  This is certainly true for open(2), and
read(2) if you are using a network file system such as NFS.  Someone
who assumes that the only errors that they have to handle is the list
in the man page, and assumes that this list is an exhaustive listing
of all possible errors, is going to be in a *world* of hurt.

I don't think it's necessary to add a sentence that other errors can
be returned in the future, and users much check for other errors, but
if you really think people are that stupid that we need to say
something which is true for every single system call in Linux, we can
do that....

						- Ted

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH -v5] random: introduce getrandom(2) system call
  2014-07-24 23:24         ` Theodore Ts'o
@ 2014-07-24 23:27           ` Andy Lutomirski
       [not found]             ` <CALCETrVgKMVnBuzE+bCXaUPRrqhVxwv4AXmJrUJSYws5rZxhJw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
       [not found]           ` <20140724232434.GN6673-AKGzg7BKzIDYtjvyW6yDsg@public.gmane.org>
  1 sibling, 1 reply; 15+ messages in thread
From: Andy Lutomirski @ 2014-07-24 23:27 UTC (permalink / raw)
  To: Theodore Ts'o, Henrique de Moraes Holschuh, Andy Lutomirski,
	Linux Kernel Developers List, Linux API, linux-crypto

On Thu, Jul 24, 2014 at 4:24 PM, Theodore Ts'o <tytso@mit.edu> wrote:
> On Thu, Jul 24, 2014 at 05:30:19PM -0300, Henrique de Moraes Holschuh wrote:
>> > I wouldn't add the error to the man page until we actually modify the
>> > kernel to add such a restriction.
>>
>> By then, it might be too late.  It would be really sad to find ourselves
>> forced to return ENOSYS to getrandom(GRND_RANDOM) when we actually wanted to
>> return EPERM/EACCES.
>
> I wouldn't worry about.  The reality is that anyone using GRND_RANDOM
> has to be checking for error codes anyway, and if they do something
> stupid because the system call returns EPERM/EACCESS when they weren't
> expecting it, again, they are much more likely to be making many other
> fatal mistakes anyway.
>
> In general, all system calls can return errno's other than the ones
> documented in the man page.  This is certainly true for open(2), and
> read(2) if you are using a network file system such as NFS.  Someone
> who assumes that the only errors that they have to handle is the list
> in the man page, and assumes that this list is an exhaustive listing
> of all possible errors, is going to be in a *world* of hurt.
>
> I don't think it's necessary to add a sentence that other errors can
> be returned in the future, and users much check for other errors, but
> if you really think people are that stupid that we need to say
> something which is true for every single system call in Linux, we can
> do that....

I think that people might do:

try getrandom(GRND_RANDOM)
fall back to /dev/random
fall back to something intensely stupid

We want them to at least attempt the fallback from GRND_RANDOM to !GRND_RANDOM.

--Andy

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH -v5] random: introduce getrandom(2) system call
  2014-07-24 20:54         ` Andy Lutomirski
@ 2014-07-24 23:27           ` H. Peter Anvin
  0 siblings, 0 replies; 15+ messages in thread
From: H. Peter Anvin @ 2014-07-24 23:27 UTC (permalink / raw)
  To: Andy Lutomirski, Henrique de Moraes Holschuh
  Cc: Theodore Ts'o, Linux Kernel Developers List, Linux API, linux-crypto

On 07/24/2014 01:54 PM, Andy Lutomirski wrote:
> 
> Or that someone writes userspace code that gets -EPERM/-EACCESS on
> getrandom with GRND_RANDOM and falls back to something worse than
> getrandom w/o GRND_RANDOM.
> 

-ENXIO?

	-hpa

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH -v5] random: introduce getrandom(2) system call
  2014-07-24 23:24         ` Theodore Ts'o
@ 2014-07-25 12:46               ` Henrique de Moraes Holschuh
       [not found]           ` <20140724232434.GN6673-AKGzg7BKzIDYtjvyW6yDsg@public.gmane.org>
  1 sibling, 0 replies; 15+ messages in thread
From: Henrique de Moraes Holschuh @ 2014-07-25 12:46 UTC (permalink / raw)
  To: Theodore Ts'o, Andy Lutomirski, Linux Kernel Developers List,
	Linux API, linux-crypto-u79uwXL29TY76Z2rM5mHXA

On Thu, 24 Jul 2014, Theodore Ts'o wrote:
> On Thu, Jul 24, 2014 at 05:30:19PM -0300, Henrique de Moraes Holschuh wrote:
> > > I wouldn't add the error to the man page until we actually modify the
> > > kernel to add such a restriction.
> > 
> > By then, it might be too late.  It would be really sad to find ourselves
> > forced to return ENOSYS to getrandom(GRND_RANDOM) when we actually wanted to
> > return EPERM/EACCES.
> 
> I wouldn't worry about.  The reality is that anyone using GRND_RANDOM
> has to be checking for error codes anyway, and if they do something

...

> In general, all system calls can return errno's other than the ones
> documented in the man page.  This is certainly true for open(2), and
> read(2) if you are using a network file system such as NFS.  Someone

A few manpages might actually have warnings to that effect, but it is not
the rule.  Amusingly enough, the one for read(2) does, while open(2) does
not.

IMHO the getrandom(2) case is slightly different: we already know to a high
degree of confidence that we will want to convey a "permission denied"
condition to userspace for getrandom(GRND_RANDOM) sooner or later.

I'd be fine with text that mentions that GRND_RANDOM access by a process
may be restricted/rejected by system policy in the future, so code should
not assume any error return code from getrandom(GRND_RANDOM) would also
apply to getrandom() without GRND_RANDOM, and must degrade gracefully and
safely in that case.

> I don't think it's necessary to add a sentence that other errors can
> be returned in the future, and users much check for other errors, but
> if you really think people are that stupid that we need to say
> something which is true for every single system call in Linux, we can
> do that....

Well, I feel we could go a bit further than usual for getrandom(2), but
I've already stated my case.

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH -v5] random: introduce getrandom(2) system call
@ 2014-07-25 12:46               ` Henrique de Moraes Holschuh
  0 siblings, 0 replies; 15+ messages in thread
From: Henrique de Moraes Holschuh @ 2014-07-25 12:46 UTC (permalink / raw)
  To: Theodore Ts'o, Andy Lutomirski, Linux Kernel Developers List,
	Linux API, linux-crypto

On Thu, 24 Jul 2014, Theodore Ts'o wrote:
> On Thu, Jul 24, 2014 at 05:30:19PM -0300, Henrique de Moraes Holschuh wrote:
> > > I wouldn't add the error to the man page until we actually modify the
> > > kernel to add such a restriction.
> > 
> > By then, it might be too late.  It would be really sad to find ourselves
> > forced to return ENOSYS to getrandom(GRND_RANDOM) when we actually wanted to
> > return EPERM/EACCES.
> 
> I wouldn't worry about.  The reality is that anyone using GRND_RANDOM
> has to be checking for error codes anyway, and if they do something

...

> In general, all system calls can return errno's other than the ones
> documented in the man page.  This is certainly true for open(2), and
> read(2) if you are using a network file system such as NFS.  Someone

A few manpages might actually have warnings to that effect, but it is not
the rule.  Amusingly enough, the one for read(2) does, while open(2) does
not.

IMHO the getrandom(2) case is slightly different: we already know to a high
degree of confidence that we will want to convey a "permission denied"
condition to userspace for getrandom(GRND_RANDOM) sooner or later.

I'd be fine with text that mentions that GRND_RANDOM access by a process
may be restricted/rejected by system policy in the future, so code should
not assume any error return code from getrandom(GRND_RANDOM) would also
apply to getrandom() without GRND_RANDOM, and must degrade gracefully and
safely in that case.

> I don't think it's necessary to add a sentence that other errors can
> be returned in the future, and users much check for other errors, but
> if you really think people are that stupid that we need to say
> something which is true for every single system call in Linux, we can
> do that....

Well, I feel we could go a bit further than usual for getrandom(2), but
I've already stated my case.

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH -v5] random: introduce getrandom(2) system call
  2014-07-24 23:27           ` Andy Lutomirski
@ 2014-07-25 13:22                 ` Theodore Ts'o
  0 siblings, 0 replies; 15+ messages in thread
From: Theodore Ts'o @ 2014-07-25 13:22 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Henrique de Moraes Holschuh, Linux Kernel Developers List,
	Linux API, linux-crypto-u79uwXL29TY76Z2rM5mHXA

On Thu, Jul 24, 2014 at 04:27:36PM -0700, Andy Lutomirski wrote:
> 
> I think that people might do:
> 
> try getrandom(GRND_RANDOM)
> fall back to /dev/random
> fall back to something intensely stupid
> 
> We want them to at least attempt the fallback from GRND_RANDOM to !GRND_RANDOM.

We can't legislate against stupidity.  Seriously, the best way to do
this is to write a good userspace library and encourage application
writers to use it.

Regards,

						- Ted

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH -v5] random: introduce getrandom(2) system call
@ 2014-07-25 13:22                 ` Theodore Ts'o
  0 siblings, 0 replies; 15+ messages in thread
From: Theodore Ts'o @ 2014-07-25 13:22 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Henrique de Moraes Holschuh, Linux Kernel Developers List,
	Linux API, linux-crypto

On Thu, Jul 24, 2014 at 04:27:36PM -0700, Andy Lutomirski wrote:
> 
> I think that people might do:
> 
> try getrandom(GRND_RANDOM)
> fall back to /dev/random
> fall back to something intensely stupid
> 
> We want them to at least attempt the fallback from GRND_RANDOM to !GRND_RANDOM.

We can't legislate against stupidity.  Seriously, the best way to do
this is to write a good userspace library and encourage application
writers to use it.

Regards,

						- Ted

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH -v5] random: introduce getrandom(2) system call
  2014-07-24 14:31 [PATCH -v5] random: introduce getrandom(2) system call Theodore Ts'o
@ 2014-07-30 14:34     ` Rolf Eike Beer
       [not found] ` <1406212287-9855-1-git-send-email-tytso-3s7WtUTddSA@public.gmane.org>
  1 sibling, 0 replies; 15+ messages in thread
From: Rolf Eike Beer @ 2014-07-30 14:34 UTC (permalink / raw)
  To: Theodore Ts'o
  Cc: Linux Kernel Developers List, linux-api-u79uwXL29TY76Z2rM5mHXA,
	linux-crypto-u79uwXL29TY76Z2rM5mHXA

Theodore Ts'o wrote:

It's me again, finding only one issue per cycle :/

> 	EAGAIN		The requested entropy was not available, and
> 			getentropy(2) would have blocked if GRND_BLOCK flag
> 			was set.

"if GRND_NONBLOCK flag was not set"

Eike

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH -v5] random: introduce getrandom(2) system call
@ 2014-07-30 14:34     ` Rolf Eike Beer
  0 siblings, 0 replies; 15+ messages in thread
From: Rolf Eike Beer @ 2014-07-30 14:34 UTC (permalink / raw)
  To: Theodore Ts'o; +Cc: Linux Kernel Developers List, linux-api, linux-crypto

Theodore Ts'o wrote:

It's me again, finding only one issue per cycle :/

> 	EAGAIN		The requested entropy was not available, and
> 			getentropy(2) would have blocked if GRND_BLOCK flag
> 			was set.

"if GRND_NONBLOCK flag was not set"

Eike

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2014-07-30 14:35 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-24 14:31 [PATCH -v5] random: introduce getrandom(2) system call Theodore Ts'o
2014-07-24 15:18 ` Henrique de Moraes Holschuh
2014-07-24 15:21   ` Andy Lutomirski
2014-07-24 19:02     ` Theodore Ts'o
2014-07-24 20:30       ` Henrique de Moraes Holschuh
2014-07-24 20:54         ` Andy Lutomirski
2014-07-24 23:27           ` H. Peter Anvin
2014-07-24 23:24         ` Theodore Ts'o
2014-07-24 23:27           ` Andy Lutomirski
     [not found]             ` <CALCETrVgKMVnBuzE+bCXaUPRrqhVxwv4AXmJrUJSYws5rZxhJw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-07-25 13:22               ` Theodore Ts'o
2014-07-25 13:22                 ` Theodore Ts'o
     [not found]           ` <20140724232434.GN6673-AKGzg7BKzIDYtjvyW6yDsg@public.gmane.org>
2014-07-25 12:46             ` Henrique de Moraes Holschuh
2014-07-25 12:46               ` Henrique de Moraes Holschuh
     [not found] ` <1406212287-9855-1-git-send-email-tytso-3s7WtUTddSA@public.gmane.org>
2014-07-30 14:34   ` Rolf Eike Beer
2014-07-30 14:34     ` Rolf Eike Beer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.