[syslog-ng]syslog-ng and Linux kernel 2.4.20

Balazs Scheidler syslog-ng@lists.balabit.hu
Thu, 29 May 2003 16:08:47 +0200


hi,

this message is to inform you that syslog-ng might crash on kernels 2.4.20
due to a kernel bug. It causes syslog-ng to crash every few days.

the problem is that recvfrom() returns without touching either the sockaddr
length or the socket address. If the memory area contains a seemingly valid
AF_INET address (because of a previous invocation), then
sockaddr2address_info memcpy()s socklen (which is 256 in our case) amount of
memory to a sockaddr_in.

I've now added a workaround, and an assert statement to catch these cases.
Patch is included below, but grabbing the latest libol snapshot should also
help.

A workaround is attached:

diff -u -r1.36 -r1.37
--- io.c	30 Apr 2003 08:08:50 -0000	1.36
+++ io.c	22 May 2003 16:56:59 -0000	1.37
@@ -1,6 +1,6 @@
 /* io.c
  *
- * $Id: io.c,v 1.36 2003/04/30 08:08:50 bazsi Exp $ */
+ * $Id: io.c,v 1.37 2003/05/22 16:56:59 bazsi Exp $ */
 
 /* lsh, an implementation of the ssh protocol
  *
@@ -373,9 +373,13 @@
 	for (;;) {
 		int res;
 		
+		/* This is another workaround for Linux kernel bugs */
+		
+		((struct sockaddr *) addr)->sa_family = 0;
+		
 		res = recvfrom(closure->fd, buffer, length, 0, (struct sockaddr *) addr, (socklen_t *) addrlen);
 
-		if (*addrlen == 2) {
+		if (*addrlen == 2 || (*addrlen >= 2 && ((struct sockaddr *) addr)->sa_family == 0)) {
 			/* HACK: this is a workaround of a Linux 2.2 & 2.4 bug,
 			 * it doesn't return anything sensible in sockaddr buf 
 			 */
@@ -1013,6 +1017,7 @@
 		struct sockaddr_in *in = (struct sockaddr_in *) addr;
 		UINT32 ip, port;
 
+		assert(addr_len == sizeof(struct sockaddr_in));
 		ip = ntohl(in->sin_addr.s_addr);
 		port = ntohs(in->sin_port);
 		a = make_inet_address(c_format_cstring("%i.%i.%i.%i",


-- 
Bazsi
PGP info: KeyID 9AF8D0A9 Fingerprint CD27 CFB0 802C 0944 9CFD 804E C82C 8EB1