Skip to contentSkip to conversation

bugfix: linux kernel-ax25: fm [invalid] to [invalid] ctl SABM+

DISCUSSION Thomas Osterried 1 participant 1 message May 17, 2003

lore
Share & tools
lore
#0 lore raw

hello,

i traced down the following problem with kernel-ax25.

the problem
-----------

normal mode is DG. if ax25rtd is running, the configured mode-VC route will be used for answering my ping.

listen -a shows the following errnous behaviour:
bpq0: fm DL9SAU-1 to DK0CCC-12 ctl UI^ pid=CC(IP) len 84
IP: len 84 44.130.36.91->44.128.2.3 ihl 20 ttl 254 prot ICMP
ICMP: type Echo Request id 0 seq 0
0000 .PÆ>.................... !"#$%&'()*+,-./0123456789:;<=>?
bpq0: fm [invalid] to [invalid] ctl SABM+

netstat -a:

  Dest       Source     Device  State        Vr/Vs    Send-Q  Recv-Q
  *          *          bpq0    SABM SENT    000/000  0       0

the source code
----------------

let's take a look at /usr/src/linux/net/ax25/ax25_ip.c:

int ax25_rebuild_header(struct sk_buff *skb)

{
        struct sk_buff *ourskb;
        unsigned char *bp  = skb->data;
        ax25_address *src, *dst;

	[..]
        dst = (ax25_address *)(bp + 1);
        src = (ax25_address *)(bp + 8);

        if (arp_find(bp + 1, skb))
                return 1;
	[..]

        if (bp[16] == AX25_P_IP) {
                if (route->ip_mode == 'V' || (route->ip_mode == ' ' && ax25_dev->values[AX25_VALUES_IPDEFMODE])) {
			[..]
                        ax25_address src_c;
                        ax25_address dst_c;
			
                        if ((ourskb = skb_copy(skb, GFP_ATOMIC)) == NULL) {
                                kfree_skb(skb);
                                restore_flags(flags);
                                return 1;
                        }
			[..]
			// now we have a private skb copy in ourskb

			kfree_skb(skb);
			// now skb is freed.
			// this affekts skb->data and thus also the pointers
			// dst and src assigned to it

			src_c = *src;
			dst_c = *dst;
			// src_c and dst_c will now refer to a free'd memory segment, which may contain a random value

			[..]
                        ax25_send_frame(ourskb, ax25_dev->values[AX25_VALUES_PACLEN], &src_c, &dst_c, route->digipeat, dev);
			
			// now sending the bogous SABM

bugfix
------

*** ax25_ip.c.orig Fri Oct 12 23:22:49 2001
--- ax25_ip.c Sat May 17 17:01:06 2003
***************
*** 161,168 ****

  			kfree_skb(skb);

! src_c = *src;
! dst_c = *dst;

skb_pull(ourskb, AX25_HEADER_LEN - 1); /* Keep PID */
ourskb->nh.raw = ourskb->data;
--- 161,172 ----

  			kfree_skb(skb);

! // dl9sau: bugfix
! // after kfree_skb(), dst and src which were pointer to bp which is part of skb->data would not be valid anymore
! // hope that after skb_pull(ourskb, ..) our dsc_c and src_c will not become invalid
! bp = ourskb->data;
! dst_c = *(ax25_address *)(bp + 1);
! src_c = *(ax25_address *)(bp + 8);

  			skb_pull(ourskb, AX25_HEADER_LEN - 1);	/* Keep PID */
  			ourskb->nh.raw = ourskb->data;

final test:
-----------
bpq0: fm DL9SAU-1 to DK0CCC-12 ctl UI^ pid=CC(IP) len 84
IP: len 84 44.130.36.91->44.128.2.3 ihl 20 ttl 254 prot ICMP
ICMP: type Echo Request id 0 seq 0
0000 ÙUÆ>.%.................. !"#$%&'()*+,-./0123456789:;<=>?
bpq0: fm DK0CCC-12 to DL9SAU-1 ctl SABM+
bpq0: fm DL9SAU-1 to DK0CCC-12 ctl UA-
bpq0: fm DK0CCC-12 to DL9SAU-1 ctl I00^ pid=CC(IP) len 84
IP: len 84 44.128.2.3->44.130.36.91 ihl 20 ttl 64 prot ICMP
ICMP: type Echo Reply id 0 seq 0
0000 ÙUÆ>.%.................. !"#$%&'()*+,-./0123456789:;<=>?
bpq0: fm DL9SAU-1 to DK0CCC-12 ctl RR1v

affected kernels are 2.2.x and 2.4.x.

some time ago i diskussed a problem with kernel oopses due to corrupted ax25 control blocks. maybe it was caused by this bug. Brian <n1uro> reported that the oopses went away after he turned off ax25rtd.

73,

- thomas dl9sau

-
To unsubscribe from this list: send the line "unsubscribe linux-hams" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html