[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