X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fllc%2Fllc_input.c;h=d62e0f9b9da3edca21a8292bc321764aa1866187;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=4da6976efc9c716b1460af2549a3a36f98849f71;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c index 4da6976ef..d62e0f9b9 100644 --- a/net/llc/llc_input.c +++ b/net/llc/llc_input.c @@ -99,22 +99,27 @@ out: static inline int llc_fixup_skb(struct sk_buff *skb) { u8 llc_len = 2; - struct llc_pdu_sn *pdu; + struct llc_pdu_un *pdu; - if (!pskb_may_pull(skb, sizeof(*pdu))) + if (unlikely(!pskb_may_pull(skb, sizeof(*pdu)))) return 0; - pdu = (struct llc_pdu_sn *)skb->data; + pdu = (struct llc_pdu_un *)skb->data; if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) == LLC_PDU_TYPE_U) llc_len = 1; llc_len += 2; + + if (unlikely(!pskb_may_pull(skb, llc_len))) + return 0; + skb->h.raw += llc_len; skb_pull(skb, llc_len); if (skb->protocol == htons(ETH_P_802_2)) { u16 pdulen = eth_hdr(skb)->h_proto, data_size = ntohs(pdulen) - llc_len; - skb_trim(skb, data_size); + if (unlikely(pskb_trim_rcsum(skb, data_size))) + return 0; } return 1; } @@ -132,7 +137,7 @@ static inline int llc_fixup_skb(struct sk_buff *skb) * data now), it queues this frame in the connection's backlog. */ int llc_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt) + struct packet_type *pt, struct net_device *orig_dev) { struct llc_sap *sap; struct llc_pdu_sn *pdu; @@ -165,18 +170,23 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, * LLC functionality */ if (sap->rcv_func) { - sap->rcv_func(skb, dev, pt); - goto out; + sap->rcv_func(skb, dev, pt, orig_dev); + goto out_put; } dest = llc_pdu_type(skb); if (unlikely(!dest || !llc_type_handlers[dest - 1])) - goto drop; + goto drop_put; llc_type_handlers[dest - 1](sap, skb); +out_put: + llc_sap_put(sap); out: return 0; drop: kfree_skb(skb); goto out; +drop_put: + kfree_skb(skb); + goto out_put; handle_station: if (!llc_station_handler) goto drop;