Re: Exceptions in 2.1 (help with 2.1.125 ip_masq oops)

David Woodhouse (David.Woodhouse@mvhi.com)
Mon, 26 Oct 1998 09:55:37 +0000


mack@sofo.uni-stuttgart.de said:
> I think I'm having the same problems, but not with ISDN, but in an
> masquerading setup:

Sounds reasonable - it doesn't look like the demasq code actually checks the
length of the received packet against the length of the sk_buff it's in before
trying to checksum it.

Try applying this patch, and see if it catches the problem.

How often does it happen?

If it's not a production box, try triggering it by sending fake TCP packets to
a port > 64000, with a length in the IP header that's greater than the
length of the packet you send.

--- linux/net/ipv4/ip_masq.c.nocheck Fri Oct 23 11:49:11 1998
+++ linux/net/ipv4/ip_masq.c Fri Oct 23 13:24:35 1998
@@ -1703,6 +1703,25 @@
* this function.
*/

+
+static void formatoutput_byte_hexdump(unsigned char *data, int num)
+{
+ int c;
+
+ if (num > 64) num = 64;
+
+ for (c=0; c< num;)
+ {
+ printk("%5.5X: %2.2X",c,data[c]);
+
+ for (c++ ; c%16 && c<num; c++)
+ {
+ printk(" %2.2X",data[c]);
+ }
+ printk("\n");
+ }
+}
+
int ip_fw_demasquerade(struct sk_buff **skb_p)
{
struct sk_buff *skb = *skb_p;
@@ -1758,6 +1777,24 @@
{
case CHECKSUM_NONE:
doff = proto_doff(iph->protocol, h.raw);
+ if ((h.raw + size) > skb->tail)
+ {
+ /* Packet of length iph->tot_len doesn't fit in the skb!
+ * Whinge like buggery. DW.
+ */
+
+ printk(KERN_CRIT "Bad packet in ip_fw_demasquerade()\n");
+ printk(KERN_CRIT "Standard 2.1.125 kernel would have oopsed and died now\n");
+ printk(KERN_CRIT "Reported size in IP header: %x (+ offset %x = %x)\n",size, doff, size + doff);
+ printk(KERN_CRIT "Size of actual data in sk_buff: %x\n", skb->len);
+ printk(KERN_CRIT "h.raw + size = %p, skb->tail = %p\n",h.raw + size, skb->tail);
+ if (skb->dev && skb->dev->name)
+ printk(KERN_CRIT "Packet arrived on interface %s\n", skb->dev->name);
+ printk(KERN_CRIT "Packet dump follows...\n");
+ formatoutput_byte_hexdump(skb->h.raw, skb->len);
+
+ return -1;
+ }
csum = csum_partial(h.raw + doff, size - doff, 0);
skb->csum = csum_partial(h.raw , doff, csum);

---- ---- ----
David Woodhouse David.Woodhouse@mvhi.com Office: (+44) 1223 810302
Project Leader, Process Information Systems Mobile: (+44) 976 658355
Axiom (Cambridge) Ltd., Swaffham Bulbeck, Cambridge, CB5 0NA, UK.
finger dwmw2@ferret.lmh.ox.ac.uk for PGP key.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/