Critical EGD handling in 2.1.1p1
Damien Miller
djm at mindrot.org
Wed Jun 21 09:07:18 EST 2000
On Tue, 20 Jun 2000, Lutz Jaenicke wrote:
> Hi,
>
> when running OpenSSH with EGD as entropy source, the sshd server connects
> to the EGD socket and leaves it open to re-seed on the fly.
> Unfortunately the connection is not checked when re-seeding, so that
> a failure or restart of EGD will lead to a "fatal()" abort of the sshd
> server process.
>
> Since a dying server process can not be accepted, I would recommend to
> not have sshd call it "fatal()" if EGD cannot be queried and there is
> already enough seed available.
Thanks for the report. How does the attached patch look?
Regards,
Damien Miller
--
| "Bombay is 250ms from New York in the new world order" - Alan Cox
| Damien Miller - http://www.mindrot.org/
| Email: djm at mindrot.org (home) -or- djm at ibs.com.au (work)
-------------- next part --------------
? scp.0
? ssh-add.0
? ssh-agent.0
? ssh-keygen.0
? ssh.0
? sshd.0
? configure
? config.h.in
? config.log
? config.h
? config.cache
? config.status
? Makefile
? ssh_prng_cmds
Index: entropy.c
===================================================================
RCS file: /var/cvs/openssh/entropy.c,v
retrieving revision 1.14
diff -u -r1.14 entropy.c
--- entropy.c 2000/06/18 04:07:04 1.14
+++ entropy.c 2000/06/20 23:06:14
@@ -70,21 +70,25 @@
{
static int egd_socket = -1;
int c;
+ int egd_error;
char egd_message[2] = { 0x02, 0x00 };
struct sockaddr_un addr;
int addr_len;
+ egd_error = 0;
+
+retry:
+
memset(&addr, '\0', sizeof(addr));
addr.sun_family = AF_UNIX;
-
- /* FIXME: compile time check? */
+
if (sizeof(EGD_SOCKET) > sizeof(addr.sun_path))
fatal("Random pool path is too long");
-
+
strlcpy(addr.sun_path, EGD_SOCKET, sizeof(addr.sun_path));
-
+
addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(EGD_SOCKET);
-
+
if (egd_socket == -1) {
egd_socket = socket(AF_UNIX, SOCK_STREAM, 0);
if (egd_socket == -1)
@@ -95,17 +99,37 @@
if (len > 255)
fatal("Too many bytes to read from EGD");
-
+
/* Send blocking read request to EGD */
egd_message[1] = len;
c = atomicio(write, egd_socket, egd_message, sizeof(egd_message));
- if (c == -1)
- fatal("Couldn't write to EGD socket \"%s\": %s", EGD_SOCKET, strerror(errno));
+ if (c == -1) {
+ if (egd_error) {
+ fatal("Couldn't write to EGD socket \"%s\": %s",
+ EGD_SOCKET, strerror(errno));
+ } else {
+ egd_error = 1;
+ error("Couldn't write to EGD socket \"%s\": %s",
+ EGD_SOCKET, strerror(errno));
+ goto retry;
+ }
+ }
c = atomicio(read, egd_socket, buf, len);
if (c <= 0)
- fatal("Couldn't read from EGD socket \"%s\": %s", EGD_SOCKET, strerror(errno));
+ if (c == -1) {
+ if (egd_error) {
+ fatal("Couldn't read from EGD socket \"%s\": %s",
+ EGD_SOCKET, strerror(errno));
+ } else {
+ egd_error = 1;
+ egd_socket = -1;
+ error("Couldn't read from EGD socket \"%s\": %s",
+ EGD_SOCKET, strerror(errno));
+ goto retry;
+ }
+ }
}
#else /* !EGD_SOCKET */
#ifdef RANDOM_POOL
More information about the openssh-unix-dev
mailing list