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