summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Delvare <jdelvare@suse.de>2007-04-10 23:06:06 +0200
committerAdrian Bunk <bunk@stusta.de>2007-04-10 23:06:06 +0200
commit132d8d23a0a2726fb2375fcac89119e28858eb6f (patch)
treedbf72c10b87066b1deec0f30a5efb7064ffc0e29
parente6f8caf0c41f27510c8a0c43a29b2e6f62a2dc56 (diff)
APPLETALK: Fix a remotely triggerable crash (CVE-2007-1357)
When we receive an AppleTalk frame shorter than what its header says, we still attempt to verify its checksum, and trip on the BUG_ON() at the end of function atalk_sum_skb() because of the length mismatch. This has security implications because this can be triggered by simply sending a specially crafted ethernet frame to a target victim, effectively crashing that host. Thus this qualifies, I think, as a remote DoS. Here is the frame I used to trigger the crash, in npg format: <Appletalk Killer> { # Ethernet header ----- XX XX XX XX XX XX # Destination MAC 00 00 00 00 00 00 # Source MAC 00 1D # Length # LLC header ----- AA AA 03 08 00 07 80 9B # Appletalk # Appletalk header ----- 00 1B # Packet length (invalid) 00 01 # Fake checksum 00 00 00 00 # Destination and source networks 00 00 00 00 # Destination and source nodes and ports # Payload ----- 0C 0D 0E 0F 10 11 12 13 14 } The destination MAC address must be set to those of the victim. The severity is mitigated by two requirements: * The target host must have the appletalk kernel module loaded. I suspect this isn't so frequent. * AppleTalk frames are non-IP, thus I guess they can only travel on local networks. I am no network expert though, maybe it is possible to somehow encapsulate AppleTalk packets over IP. The bug has been reported back in June 2004: http://bugzilla.kernel.org/show_bug.cgi?id=2979 But it wasn't investigated, and was closed in July 2006 as both reporters had vanished meanwhile. This code was new in kernel 2.6.0-test5: http://git.kernel.org/?p=linux/kernel/git/tglx/history.git;a=commitdiff;h=7ab442d7e0a76402c12553ee256f756097cae2d2 And not modified since then, so we can assume that vanilla kernels 2.6.0-test5 and later, and distribution kernels based thereon, are affected. Note that I still do not know for sure what triggered the bug in the real-world cases. The frame could have been corrupted by the kernel if we have a bug hiding somewhere. But more likely, we are receiving the faulty frame from the network. Signed-off-by: Jean Delvare <jdelvare@suse.de> Signed-off-by: Adrian Bunk <bunk@stusta.de>
-rw-r--r--net/appletalk/ddp.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 697ac55e29dc..5f33e4817a58 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1423,10 +1423,13 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
/*
* Size check to see if ddp->deh_len was crap
* (Otherwise we'll detonate most spectacularly
- * in the middle of recvmsg()).
+ * in the middle of atalk_checksum() or recvmsg()).
*/
- if (skb->len < sizeof(*ddp))
+ if (skb->len < sizeof(*ddp) || skb->len < ddphv.deh_len) {
+ pr_debug("AppleTalk: dropping corrupted frame (deh_len=%u, "
+ "skb->len=%u)\n", ddphv.deh_len, skb->len);
goto freeit;
+ }
/*
* Any checksums. Note we don't do htons() on this == is assumed to be