Implementing getrandom/getentropy, anybody?

2019-10-29 Thread Andrew Eggenberger
Updated patch attached.

Thank you.
Andrew

>From a4e3233c9c21189267a9fb80588ff08f28f31729 Mon Sep 17 00:00:00 2001
From: Andrew Eggenberger 
Date: Tue, 29 Oct 2019 23:19:32 -0500
Subject: [PATCH] add getrandom and getentropy implementations

---
 sysdeps/mach/hurd/getentropy.c | 65 ++
 sysdeps/mach/hurd/getrandom.c  | 39 
 2 files changed, 104 insertions(+)
 create mode 100644 sysdeps/mach/hurd/getentropy.c
 create mode 100644 sysdeps/mach/hurd/getrandom.c

diff --git a/sysdeps/mach/hurd/getentropy.c b/sysdeps/mach/hurd/getentropy.c
new file mode 100644
index 00..28534f8d83
--- /dev/null
+++ b/sysdeps/mach/hurd/getentropy.c
@@ -0,0 +1,65 @@
+/* Implementation of getentropy based on the getrandom system call.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   .  */
+
+#include 
+#include 
+#include 
+#include 
+
+/* Write LENGTH bytes of randomness starting at BUFFER.  Return 0 on
+   success and -1 on failure.  */
+int
+getentropy (void *buffer, size_t length)
+{
+  /* The interface is documented to return EIO for buffer lengths
+ longer than 256 bytes.  */
+  if (length > 256)
+{
+  __set_errno (EIO);
+  return -1;
+}
+
+  /* Try to fill the buffer completely.  Even with the 256 byte limit
+ above, we might still receive an EINTR error (when blocking
+ during boot).  */
+  void *end = buffer + length;
+  while (buffer < end)
+{
+  /* NB: No cancellation point.  */
+  ssize_t bytes = getrandom(buffer, end - buffer, 0);
+  if (bytes < 0)
+{
+  if (errno == EINTR)
+/* Try again if interrupted by a signal.  */
+continue;
+  else
+return -1;
+}
+  if (bytes == 0)
+{
+  /* No more bytes available.  This should not happen under
+ normal circumstances.  */
+  __set_errno (EIO);
+  return -1;
+}
+  /* Try again in case of a short read.  */
+  buffer += bytes;
+}
+  return 0;
+}
+
diff --git a/sysdeps/mach/hurd/getrandom.c b/sysdeps/mach/hurd/getrandom.c
new file mode 100644
index 00..837de1a2d2
--- /dev/null
+++ b/sysdeps/mach/hurd/getrandom.c
@@ -0,0 +1,39 @@
+/* Hurdish implementation of getrandom
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   .  */
+
+#include 
+#include 
+#include 
+
+/* Write up to LENGTH bytes of randomness starting at BUFFER.
+   Return the number of bytes written, or -1 on error.  */
+ssize_t
+getrandom (void *buffer, size_t length, unsigned int flags)
+{
+  char* random_source = "/dev/urandom";
+  int amount_read, fp;
+
+  if (flags & GRND_RANDOM){
+random_source = "/dev/random";
+  }
+
+  fp = open(random_source, O_RDONLY);
+  amount_read = read(fp, buffer, length);
+  close(fp);
+  return amount_read;
+}
-- 
2.23.0



Re: [PATCH] 1(3) hurd+glibc: Support for file record locking

2019-10-29 Thread Samuel Thibault
Hello,

Svante Signell, le jeu. 12 sept. 2019 10:15:27 +0200, a ecrit:
> Attached is the first part of the patches for file record locking:

Now (at last!) applied, thanks a lot!

Samuel



Re: [PATCH] 1(3) hurd+glibc: Support for file record locking

2019-10-29 Thread Svante Signell
On Mon, 2019-10-28 at 01:40 +0100, Samuel Thibault wrote:
> There was an issue with rlock-tweak.c, revealed by the tdb testsuite:
> 
> Index: hurd-debian/libfshelp/rlock-tweak.c
> ===
> --- hurd-debian.orig/libfshelp/rlock-tweak.c
> +++ hurd-debian/libfshelp/rlock-tweak.c
> 
> + else if (l->start < start && start <= l->start + l->len
> +  && (len == 0 || start + len > l->start + l->len))
> /* Our start falls within the locked region or exactly one byte after
> it and our end falls beyond it.  We know that we cannot consume the
> entire region.  */
> 
> Apart from that it seemed to work just fine. I'll let the glibc
> testsuite run this night to be sure before committing.

Nice catch. I never tried running the tdb testsuite explicitly during
the years, only when trying to build tdb itself. How did the glibc
testsuite run go?

Thanks!




Re: [PATCH] 2(3) hurd+glibc: Support for file record locking

2019-10-29 Thread Samuel Thibault
Svante Signell, le mar. 29 oct. 2019 10:20:27 +0100, a ecrit:
> Maybe it did not hit me since I built and installed the patched
> hurd+glibc packages simultaneously?

Yes, that's why. Renumbering introduces incompatibility. If you upgrade
both at once you aren't hit.

The testsuite went fine, so I'll commit when I get the time to do it
properly, thanks!

Samuel



Re: [PATCH] 2(3) hurd+glibc: Support for file record locking

2019-10-29 Thread Svante Signell
On Sun, 2019-10-27 at 21:06 +0100, Samuel Thibault wrote:
> Svante Signell, le jeu. 12 sept. 2019 10:23:55 +0200, a ecrit:
> > @@ -358,6 +357,18 @@ routine file_reparent (
> >  skip;  /* Was: file_get_children.  */
> >  skip;  /* Was: file_get_source.  */
> >  
> > +
> > +/* Do fcntl type locking on FILE. CMD is from the set F_GETLK64,
> > + F_SETLK64, F_SETLKW64. FLOCK64 is passed by the user and is as
> > + defined by . RENDEZVOUS is MACH_PORT_NULL for per opened
> > + file locking and !MACH_PORT_NULL for per process file locking */
> > +routine file_record_lock (
> > +   file: file_t;
> > +   RPT
> > +   cmd: int;
> > +   inout flock64: flock_t;
> > +   rendezvous: mach_port_send_t);
> > +
> >  /* Overlay a task with a file.  Necessary initialization,
> > including authentication changes associated with set[ug]id
> > execution must be handled by the filesystem.  Filesystems normally
> > implement this by
> 
> I'm only realizing this, now that I see that rebooting with the
> patches applied on hurd fails completely: never insert an RPC between
> existing ones! That renumbers everything, we do not want that at any
> rate. I'll fix that along committing.

Thank you Samuel for finding time to review the patches. Regarding the
placement of file_record_lock in fs.defs I have not changed it. That
place was selected by Neal in 2001. Of course a lot has happened since
then. Sorry for not realising that it should be placed in time order,
but I never had a failing boot due to this error. Maybe it did not hit
me since I built and installed the patched hurd+glibc packages
simultaneously?

Thanks!




Re: Implementing getrandom/getentropy, anybody?

2019-10-29 Thread Samuel Thibault
Andrew Eggenberger, le mar. 29 oct. 2019 00:30:17 -0500, a ecrit:
> Here's a really quick implementation just to get some feedback.

That's already a beginning.

The implementation shouldn't go in the platform-generic stdlib/ files,
but in sysdeps/mach/hurd/

> @@ -24,8 +24,11 @@
>  int
>  getentropy (void *buffer, size_t length)
>  {
> -  __set_errno (ENOSYS);
> -  return -1;
> +  size_t bytes_read;
> +  bytes_read = getrandom(buffer, length, 0);
> +  if (bytes_read != length){

Getrandom is allowed not to return the proper length. Getentropy should
have a loop around it. The ./sysdeps/unix/sysv/linux/getentropy.c
version might actually be used as such.

>  ssize_t
>  getrandom (void *buffer, size_t length, unsigned int flags)
>  {
> -  __set_errno (ENOSYS);
> -  return -1;
> -}
> +  FILE * random_source;
> +  if (flags & GRND_RANDOM){
> +random_source = fopen("/dev/random", "r");
> +return fread(buffer, 1, length, random_source);

Rather use open/read, there is no need for buffering. Also remember to
close it. You can factorize the open/read/close calls by only setting a
char* variable in the if.

Samuel