[IFB]: Fix crash on input device removal
The input_device pointer is not refcounted, which means the device may disappear while packets are queued, causing a crash when ifb passes packets with a stale skb->dev pointer to netif_rx(). Fix by storing the interface index instead and do a lookup where neccessary. Signed-off-by: Patrick McHardy <kaber@trash.net> Acked-by: Jamal Hadi Salim <hadi@cyberus.ca> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
db8b22550d
commit
c01003c205
@@ -188,7 +188,7 @@ enum {
|
||||
* @sk: Socket we are owned by
|
||||
* @tstamp: Time we arrived
|
||||
* @dev: Device we arrived on/are leaving by
|
||||
* @input_dev: Device we arrived on
|
||||
* @iif: ifindex of device we arrived on
|
||||
* @h: Transport layer header
|
||||
* @nh: Network layer header
|
||||
* @mac: Link layer header
|
||||
@@ -235,7 +235,8 @@ struct sk_buff {
|
||||
struct sock *sk;
|
||||
struct skb_timeval tstamp;
|
||||
struct net_device *dev;
|
||||
struct net_device *input_dev;
|
||||
int iif;
|
||||
/* 4 byte hole on 64 bit*/
|
||||
|
||||
union {
|
||||
struct tcphdr *th;
|
||||
|
||||
@@ -352,10 +352,13 @@ tcf_change_indev(struct tcf_proto *tp, char *indev, struct rtattr *indev_tlv)
|
||||
static inline int
|
||||
tcf_match_indev(struct sk_buff *skb, char *indev)
|
||||
{
|
||||
struct net_device *dev;
|
||||
|
||||
if (indev[0]) {
|
||||
if (!skb->input_dev)
|
||||
if (!skb->iif)
|
||||
return 0;
|
||||
if (strcmp(indev, skb->input_dev->name))
|
||||
dev = __dev_get_by_index(skb->iif);
|
||||
if (!dev || strcmp(indev, dev->name))
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user