From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: Justin Forbes <jmforbes@linuxtx.org>,
Zwane Mwaikambo <zwane@arm.linux.org.uk>,
"Theodore Ts'o" <tytso@mit.edu>,
Randy Dunlap <rdunlap@xenotime.net>,
Dave Jones <davej@redhat.com>,
Chuck Wolber <chuckw@quantumlinux.com>,
Chris Wedgwood <reviews@ml.cw.f00f.org>,
Michael Krufky <mkrufky@linuxtv.org>,
Chuck Ebbert <cebbert@redhat.com>,
torvalds@linux-foundation.org, akpm@linux-foundation.org,
alan@lxorguk.ukuu.org.uk, bunk@stusta.de,
Patrick McHardy <kaber@trash.net>,
Jamal Hadi Salim <hadi@cyberus.ca>,
"David S. Miller" <davem@davemloft.net>
Subject: [patch 14/31] Fix IFB net driver input device crashes
Date: Wed, 11 Apr 2007 15:52:03 -0700 [thread overview]
Message-ID: <20070411225203.GO24814@kroah.com> (raw)
In-Reply-To: <20070411225100.GA24814@kroah.com>
[-- Attachment #1: fix-ifb-net-driver-input-device-crashes.patch --]
[-- Type: text/plain, Size: 4653 bytes --]
-stable review patch. If anyone has any objections, please let us know.
------------------
From: Patrick McHardy <kaber@trash.net>
[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>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/net/ifb.c | 35 +++++++++++++----------------------
include/linux/skbuff.h | 5 +++--
include/net/pkt_cls.h | 7 +++++--
net/core/dev.c | 8 ++++----
net/core/skbuff.c | 2 +-
net/sched/act_mirred.c | 2 +-
6 files changed, 27 insertions(+), 32 deletions(-)
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -96,17 +96,24 @@ static void ri_tasklet(unsigned long dev
skb->tc_verd = SET_TC_NCLS(skb->tc_verd);
stats->tx_packets++;
stats->tx_bytes +=skb->len;
+
+ skb->dev = __dev_get_by_index(skb->iif);
+ if (!skb->dev) {
+ dev_kfree_skb(skb);
+ stats->tx_dropped++;
+ break;
+ }
+ skb->iif = _dev->ifindex;
+
if (from & AT_EGRESS) {
dp->st_rx_frm_egr++;
dev_queue_xmit(skb);
} else if (from & AT_INGRESS) {
-
dp->st_rx_frm_ing++;
+ skb_pull(skb, skb->dev->hard_header_len);
netif_rx(skb);
- } else {
- dev_kfree_skb(skb);
- stats->tx_dropped++;
- }
+ } else
+ BUG();
}
if (netif_tx_trylock(_dev)) {
@@ -157,26 +164,10 @@ static int ifb_xmit(struct sk_buff *skb,
stats->rx_packets++;
stats->rx_bytes+=skb->len;
- if (!from || !skb->input_dev) {
-dropped:
+ if (!(from & (AT_INGRESS|AT_EGRESS)) || !skb->iif) {
dev_kfree_skb(skb);
stats->rx_dropped++;
return ret;
- } else {
- /*
- * note we could be going
- * ingress -> egress or
- * egress -> ingress
- */
- skb->dev = skb->input_dev;
- skb->input_dev = dev;
- if (from & AT_INGRESS) {
- skb_pull(skb, skb->dev->hard_header_len);
- } else {
- if (!(from & AT_EGRESS)) {
- goto dropped;
- }
- }
}
if (skb_queue_len(&dp->rq) >= dev->tx_queue_len) {
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -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;
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -352,10 +352,13 @@ tcf_change_indev(struct tcf_proto *tp, c
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;
}
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1741,8 +1741,8 @@ static int ing_filter(struct sk_buff *sk
if (dev->qdisc_ingress) {
__u32 ttl = (__u32) G_TC_RTTL(skb->tc_verd);
if (MAX_RED_LOOP < ttl++) {
- printk(KERN_WARNING "Redir loop detected Dropping packet (%s->%s)\n",
- skb->input_dev->name, skb->dev->name);
+ printk(KERN_WARNING "Redir loop detected Dropping packet (%d->%d)\n",
+ skb->iif, skb->dev->ifindex);
return TC_ACT_SHOT;
}
@@ -1775,8 +1775,8 @@ int netif_receive_skb(struct sk_buff *sk
if (!skb->tstamp.off_sec)
net_timestamp(skb);
- if (!skb->input_dev)
- skb->input_dev = skb->dev;
+ if (!skb->iif)
+ skb->iif = skb->dev->ifindex;
orig_dev = skb_bond(skb);
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -497,7 +497,7 @@ struct sk_buff *skb_clone(struct sk_buff
n->tc_verd = SET_TC_VERD(skb->tc_verd,0);
n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd);
n->tc_verd = CLR_TC_MUNGED(n->tc_verd);
- C(input_dev);
+ C(iif);
#endif
skb_copy_secmark(n, skb);
#endif
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -199,7 +199,7 @@ bad_mirred:
skb2->tc_verd = SET_TC_FROM(skb2->tc_verd, at);
skb2->dev = dev;
- skb2->input_dev = skb->dev;
+ skb2->iif = skb->dev->ifindex;
dev_queue_xmit(skb2);
spin_unlock(&m->tcf_lock);
return m->tcf_action;
--
next prev parent reply other threads:[~2007-04-11 23:03 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20070411224329.866978349@mini.kroah.org>
2007-04-11 22:51 ` [patch 00/31] [00/@num@] -stable review Greg KH
2007-04-11 22:51 ` [patch 01/31] kbuild: fix dependency generation Greg KH
2007-04-11 22:51 ` [patch 02/31] i386: fix file_read_actor() and pipe_read() for original i386 systems Greg KH
2007-04-11 22:51 ` [patch 03/31] sky2: reliable recovery Greg KH
2007-04-11 22:51 ` [patch 04/31] skge: turn carrier off when down Greg KH
2007-04-11 22:51 ` [patch 05/31] sky2: " Greg KH
2007-04-11 22:51 ` [patch 06/31] sky2: turn on clocks when doing resume Greg KH
2007-04-11 22:51 ` [patch 07/31] sky2: phy workarounds for Yukon EC-U A1 Greg KH
2007-04-11 22:51 ` [patch 08/31] DVB: tda10086: fix DiSEqC message length Greg KH
2007-04-11 22:51 ` [patch 09/31] DVB: pluto2: fix incorrect TSCR register setting Greg KH
2007-04-11 22:51 ` [patch 10/31] HID: Do not discard truncated input reports Greg KH
2007-04-11 22:51 ` [patch 11/31] Fix calculation for size of filemap_attr array in md/bitmap Greg KH
2007-04-11 22:51 ` [patch 12/31] 8139too: RTNL and flush_scheduled_work deadlock Greg KH
2007-04-11 22:51 ` [patch 13/31] NETFILTER: ipt_CLUSTERIP: fix oops in checkentry function Greg KH
2007-04-11 22:52 ` Greg KH [this message]
2007-04-11 22:52 ` [patch 15/31] Fix length validation in rawv6_sendmsg() Greg KH
2007-04-11 22:52 ` [patch 16/31] Fix scsi sense handling Greg KH
2007-04-11 22:52 ` [patch 17/31] Fix TCP receiver side SWS handling Greg KH
2007-04-11 22:52 ` [patch 18/31] Fix IPSEC replay window handling Greg KH
2007-04-11 22:52 ` [patch 19/31] Fix tcindex classifier ABI borkage Greg KH
2007-04-11 22:52 ` [patch 20/31] Fix TCP slow_start_after_idle sysctl Greg KH
2007-04-11 22:52 ` [patch 21/31] ide: use correct IDE error recovery Greg KH
2007-04-11 22:52 ` [patch 22/31] knfsd: allow nfsd READDIR to return 64bit cookies Greg KH
2007-04-11 22:52 ` [patch 23/31] softmac: avoid assert in ieee80211softmac_wx_get_rate Greg KH
2007-04-11 22:52 ` [patch 24/31] libata bugfix: preserve LBA bit for HDIO_DRIVE_TASK Greg KH
2007-04-11 22:52 ` [patch 25/31] ahci.c: walkaround for SB600 SATA internal error issue Greg KH
2007-04-11 22:52 ` [patch 26/31] fix lba48 bug in libata fill_result_tf() Greg KH
2007-04-11 22:52 ` [patch 27/31] libata: Clear tf before doing request sense (take 3) Greg KH
2007-04-11 22:52 ` [patch 28/31] revert "retries in ext3_prepare_write() violate ordering requirements" Greg KH
2007-04-11 22:52 ` [patch 29/31] revert "retries in ext4_prepare_write() " Greg KH
2007-04-11 22:53 ` [patch 30/31] fix page leak during core dump Greg KH
2007-04-11 22:53 ` [patch 31/31] Update libata drive blacklist to the latest from 2.6.21 Greg KH
2007-04-12 6:14 ` [patch 00/31] [00/@num@] -stable review Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070411225203.GO24814@kroah.com \
--to=gregkh@suse.de \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=bunk@stusta.de \
--cc=cebbert@redhat.com \
--cc=chuckw@quantumlinux.com \
--cc=davej@redhat.com \
--cc=davem@davemloft.net \
--cc=hadi@cyberus.ca \
--cc=jmforbes@linuxtx.org \
--cc=kaber@trash.net \
--cc=linux-kernel@vger.kernel.org \
--cc=mkrufky@linuxtv.org \
--cc=rdunlap@xenotime.net \
--cc=reviews@ml.cw.f00f.org \
--cc=stable@kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=tytso@mit.edu \
--cc=zwane@arm.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.