[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:24:22 +0300 |
On Tue, Nov 29, 2022 at 11:47 AM Samuel Thibault
<samuel.thibault@gnu.org> wrote:
> Sergey Bugaev, le mar. 29 nov. 2022 09:22:20 +0300, a ecrit:
> > Hello everyone!
> >
> > I am indeed out of the army, alive and in one piece.
>
> !! \o/ !!
>
> I have to say I was very worried, I'm glad that you are back in one
> piece.
Thank you so much for caring! I am in fact _so_ glad that my online
friends & peers not only remembered me, but actually cared & worried
about me throughout all this.
Fortunately — while this has been a year of my personal hell, of being
mistreated, disrespected, and humiliated — they never sent me to
you-know-where. I spent all the time on a military airdrom near
Moscow. So there's not that much physical injury that could happen to
me, mental health notwithstanding.
> > As for the SSH/arc4random issue: I believe a better workaround would
> > be for glibc to cache the /dev/urandom port between calls to getrandom
> > (), the same way that it caches socket server ports (see
> > hurd/hurdsock.c).
>
> Indeed, that would solve the problem while at the same time optimize
> things.
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.
The existing code supports GRND_RANDOM and GRND_NONBLOCK; the latter
we should still support in some way, the former I'm not sure about,
given that urandom and random are the same thing. Or is that a Debian
thing that glibc should not rely on?
--------------------------- >8 ------------------------------
diff --git a/sysdeps/mach/hurd/getrandom.c b/sysdeps/mach/hurd/getrandom.c
index ad2d3ba3..9c0ea5db 100644
--- a/sysdeps/mach/hurd/getrandom.c
+++ b/sysdeps/mach/hurd/getrandom.c
@@ -16,22 +16,61 @@
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);
+ /* Re-check whether the port is still invalid, since someone
+ * could have reset it while we were waiting. */
+ server = random_server;
+ if (MACH_PORT_VALID (server))
+ goto out;
+
+ 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 +83,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)
--------------------------- 8< ------------------------------
> I'm wondering, though: does ssh fork-off other processes inside
> the chroot, that might get the same issue?
I don't think it does. In any case, there's nothing for it to exec
inside the chroot, and just forking w/o exec'ing should work, as fork
preserves ports.
Sergey
Re: lost ssh access - where is a log?, Riccardo Mottola, 2022/11/30