]> git.neil.brown.name Git - history.git/commitdiff
[LAPB]: Fix packet handlers to be PKT_CAN_SHARE_SKB.
authorDavid S. Miller <davem@nuts.ninka.net>
Mon, 6 Oct 2003 19:58:15 +0000 (12:58 -0700)
committerDavid S. Miller <davem@nuts.ninka.net>
Mon, 6 Oct 2003 19:58:15 +0000 (12:58 -0700)
drivers/net/wan/comx-proto-lapb.c
drivers/net/wan/hdlc_x25.c
drivers/net/wan/lapbether.c
include/net/lapb.h
net/lapb/lapb_in.c
net/lapb/lapb_subr.c

index 30c818601ecf86c14782f541604dae64dbaa9e43..f3d0fb325c5350be996fdbe185edd3820270699e 100644 (file)
@@ -372,6 +372,10 @@ static int comxlapb_data_indication(void *token, struct sk_buff *skb)
 
        if (ch->dev->type == ARPHRD_X25) {
                skb_push(skb, 1);
+
+               if (skb_cow(skb, 1))
+                       return NET_RX_DROP;
+
                skb->data[0] = 0;       // indicate data for X25
                skb->protocol = htons(ETH_P_X25);
        } else {
index 3f0612c4c4be34c8ab0d067da412f2753e4779dd..76e7daf5c3e1d998a4d6085656c49983c80ebe16 100644 (file)
@@ -68,7 +68,12 @@ static int x25_data_indication(void *token, struct sk_buff *skb)
        hdlc_device *hdlc = token;
        unsigned char *ptr;
 
-       ptr = skb_push(skb, 1);
+       skb_push(skb, 1);
+
+       if (skb_cow(skb, 1))
+               return NET_RX_DROP;
+
+       ptr  = skb->data;
        *ptr = 0;
 
        skb->dev = hdlc_to_dev(hdlc);
index 293ce6cf9acac85d3908446347a279849feab328..271b7c64ebca32a6ca85530552ac10254ee8ac5a 100644 (file)
@@ -89,14 +89,15 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
        int len, err;
        struct lapbethdev *lapbeth;
 
-       skb->sk = NULL;         /* Initially we don't know who it's for */
+       if (!pskb_may_pull(skb, 2))
+               goto drop;
 
        rcu_read_lock();
        lapbeth = lapbeth_get_x25_dev(dev);
        if (!lapbeth)
-               goto drop;
+               goto drop_unlock;
        if (!netif_running(lapbeth->axdev))
-               goto drop;
+               goto drop_unlock;
 
        lapbeth->stats.rx_packets++;
 
@@ -108,14 +109,17 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
 
        if ((err = lapb_data_received(lapbeth, skb)) != LAPB_OK) {
                printk(KERN_DEBUG "lapbether: lapb_data_received err - %d\n", err);
-               goto drop;
+               goto drop_unlock;
        }
 out:
        rcu_read_unlock();
        return 0;
-drop:
+drop_unlock:
        kfree_skb(skb);
        goto out;
+drop:
+       kfree_skb(skb);
+       return 0;
 }
 
 static int lapbeth_data_indication(void *token, struct sk_buff *skb)
@@ -123,7 +127,12 @@ static int lapbeth_data_indication(void *token, struct sk_buff *skb)
        struct lapbethdev *lapbeth = (struct lapbethdev *)token;
        unsigned char *ptr;
 
-       ptr  = skb_push(skb, 1);
+       skb_push(skb, 1);
+
+       if (skb_cow(skb, 1))
+               return NET_RX_DROP;
+
+       ptr  = skb->data;
        *ptr = 0x00;
 
        skb->dev      = lapbeth->axdev;
@@ -426,6 +435,7 @@ static int lapbeth_device_event(struct notifier_block *this,
 static struct packet_type lapbeth_packet_type = {
        .type = __constant_htons(ETH_P_DEC),
        .func = lapbeth_rcv,
+       .data = PKT_CAN_SHARE_SKB,
 };
 
 static struct notifier_block lapbeth_dev_notifier = {
index 50292be77a7194213972a722737417e1d4877bae..83a241043842ae75902992eb37c6cf523f80636e 100644 (file)
@@ -129,7 +129,7 @@ extern void lapb_clear_queues(struct lapb_cb *lapb);
 extern void lapb_frames_acked(struct lapb_cb *lapb, unsigned short);
 extern void lapb_requeue_frames(struct lapb_cb *lapb);
 extern int  lapb_validate_nr(struct lapb_cb *lapb, unsigned short);
-extern void lapb_decode(struct lapb_cb *lapb, struct sk_buff *, struct lapb_frame *);
+extern int lapb_decode(struct lapb_cb *lapb, struct sk_buff *, struct lapb_frame *);
 extern void lapb_send_control(struct lapb_cb *lapb, int, int, int);
 extern void lapb_transmit_frmr(struct lapb_cb *lapb);
 
index 431c6918aaf075ea7753a985b58dc6200d9e5770..2275e15a97193d0906b5479eacde304b6e204f0b 100644 (file)
@@ -702,7 +702,10 @@ void lapb_data_input(struct lapb_cb *lapb, struct sk_buff *skb)
 {
        struct lapb_frame frame;
 
-       lapb_decode(lapb, skb, &frame);
+       if (lapb_decode(lapb, skb, &frame) < 0) {
+               kfree_skb(skb);
+               return;
+       }
 
        switch (lapb->state) {
        case LAPB_STATE_0:
index 36e1769330e4c195bdb5d8faed36bc020fb7c668..e1ae5fd7302d67576dc4cb53b025c8a75912251c 100644 (file)
@@ -107,8 +107,8 @@ int lapb_validate_nr(struct lapb_cb *lapb, unsigned short nr)
  *     This routine is the centralised routine for parsing the control
  *     information for the different frame formats.
  */
-void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
-                struct lapb_frame *frame)
+int lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
+               struct lapb_frame *frame)
 {
        frame->type = LAPB_ILLEGAL;
 
@@ -118,6 +118,12 @@ void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
               skb->data[0], skb->data[1], skb->data[2]);
 #endif
 
+       /* We always need to look at 2 bytes, sometimes we need
+        * to look at 3 and those cases are handled below.
+        */
+       if (!pskb_may_pull(skb, 2))
+               return -1;
+
        if (lapb->mode & LAPB_MLP) {
                if (lapb->mode & LAPB_DCE) {
                        if (skb->data[0] == LAPB_ADDR_D)
@@ -148,6 +154,8 @@ void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
 
        if (lapb->mode & LAPB_EXTENDED) {
                if (!(skb->data[0] & LAPB_S)) {
+                       if (!pskb_may_pull(skb, 2))
+                               return -1;
                        /*
                         * I frame - carries NR/NS/PF
                         */
@@ -159,6 +167,8 @@ void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
                        frame->control[1] = skb->data[1];
                        skb_pull(skb, 2);
                } else if ((skb->data[0] & LAPB_U) == 1) {
+                       if (!pskb_may_pull(skb, 2))
+                               return -1;
                        /*
                         * S frame - take out PF/NR
                         */
@@ -206,6 +216,8 @@ void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
 
                skb_pull(skb, 1);
        }
+
+       return 0;
 }
 
 /*