bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: lost ssh access - where is a log?


From: Sergey Bugaev
Subject: Re: lost ssh access - where is a log?
Date: Tue, 29 Nov 2022 16:36:58 +0300

On Tue, Nov 29, 2022 at 4:24 PM Sergey Bugaev <bugaevc@gmail.com> wrote:
> Well, here's a preliminary patch. Please don't expect it to be any
> good, I must have forgotten all the subtleties of glibc development —
> those that I managed to learn in the first place — over the year. That
> being said, it builds; I haven't tested whether it works.

...and I already see some of the brokenness. Here's a slightly better version:

--------------------------- >8 ------------------------------
diff --git a/sysdeps/mach/hurd/getrandom.c b/sysdeps/mach/hurd/getrandom.c
index ad2d3ba3..44bf1e8f 100644
--- a/sysdeps/mach/hurd/getrandom.c
+++ b/sysdeps/mach/hurd/getrandom.c
@@ -16,22 +16,65 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */

+#include <hurd.h>
 #include <sys/random.h>
 #include <fcntl.h>
-#include <unistd.h>
-#include <not-cancel.h>
+
+__libc_rwlock_define_initialized (static, lock);
+static file_t random_server;

 extern char *__trivfs_server_name __attribute__((weak));

+static file_t
+get_random_server (int dead)
+{
+  file_t server;
+  int flags;
+
+  if (!dead)
+    {
+      /* Attempt to use the cached port, if any.  */
+      __libc_rwlock_rdlock (lock);
+      server = random_server;
+      if (MACH_PORT_VALID (server))
+        goto out;
+
+      __libc_rwlock_unlock (lock);
+    }
+
+  __libc_rwlock_wrlock (lock);
+
+  server = random_server;
+  if (MACH_PORT_VALID (server))
+    if (!dead)
+      /* Someone else has obtained a new port while we were
+         waiting for the lock.  */
+      goto out;
+    else
+      __mach_port_deallocate (__mach_task_self (), server);
+
+  flags = O_RDONLY | O_NOCTTY;
+  /* TODO: O_NONBLOCK? */
+  server = random_server = __file_name_lookup ("/dev/urandom", flags, 0);
+
+out:
+  __libc_rwlock_unlock (lock);
+
+  if (server == MACH_PORT_DEAD)
+    server = MACH_PORT_NULL;
+  return server;
+}
+
 /* 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)
 {
-  const char *random_source = "/dev/urandom";
-  int open_flags = O_RDONLY | O_CLOEXEC;
-  size_t amount_read;
-  int fd;
+  file_t server;
+  error_t err;
+  int dead = 0;
+  char *data = buffer;
+  mach_msg_type_number_t nread = length;

   if (&__trivfs_server_name && __trivfs_server_name
       && __trivfs_server_name[0] == 'r'
@@ -44,19 +87,33 @@ __getrandom (void *buffer, size_t length, unsigned
int flags)
     /* We are random, don't try to read ourselves!  */
     return length;

-  if (flags & GRND_RANDOM)
-    random_source = "/dev/random";
+again:
+  server = get_random_server (dead);
+  if (!MACH_PORT_VALID (server))
+    return -1;

-  if (flags & GRND_NONBLOCK)
-    open_flags |= O_NONBLOCK;
+  err = __io_read (server, &data, &nread, -1, length);
+  if (!dead && (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED))
+    {
+      dead = 1;
+      goto again;
+    }

-  fd = __open_nocancel(random_source, open_flags);
-  if (fd == -1)
-    return -1;
+  if (err)
+    return __hurd_fail (err);
+
+  if (data != buffer)
+    {
+      if (nread > length)
+        {
+          __vm_deallocate (__mach_task_self (), (vm_address_t) data, nread);
+          return __hurd_fail (EGRATUITOUS);
+        }
+      memcpy (buffer, data, nread);
+      __vm_deallocate (__mach_task_self (), (vm_address_t) data, nread);
+    }

-  amount_read = __read_nocancel(fd, buffer, length);
-  __close_nocancel_nostatus(fd);
-  return amount_read;
+  return nread;
 }

 libc_hidden_def (__getrandom)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]