From: Peter Oskolkov <posk@google.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, netdev@vger.kernel.org
Cc: Peter Oskolkov <posk@posk.io>, David Miller <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Sasha Levin <sashal@kernel.org>,
Captain Wiggum <captwiggum@gmail.com>,
Lars Persson <lists@bofh.nu>
Subject: [PATCH 4.9 stable 1/5] ipv6: frags: fix a lockdep false positive
Date: Fri, 26 Apr 2019 08:41:04 -0700 [thread overview]
Message-ID: <20190426154108.52277-2-posk@google.com> (raw)
In-Reply-To: <20190426154108.52277-1-posk@google.com>
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 415787d7799f4fccbe8d49cb0b8e5811be6b0389 ]
lockdep does not know that the locks used by IPv4 defrag
and IPv6 reassembly units are of different classes.
It complains because of following chains :
1) sch_direct_xmit() (lock txq->_xmit_lock)
dev_hard_start_xmit()
xmit_one()
dev_queue_xmit_nit()
packet_rcv_fanout()
ip_check_defrag()
ip_defrag()
spin_lock() (lock frag queue spinlock)
2) ip6_input_finish()
ipv6_frag_rcv() (lock frag queue spinlock)
ip6_frag_queue()
icmpv6_param_prob() (lock txq->_xmit_lock at some point)
We could add lockdep annotations, but we also can make sure IPv6
calls icmpv6_param_prob() only after the release of the frag queue spinlock,
since this naturally makes frag queue spinlock a leaf in lock hierarchy.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/ipv6/reassembly.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 74ffbcb306a6..64c8f20d3c41 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -169,7 +169,8 @@ fq_find(struct net *net, __be32 id, const struct ipv6hdr *hdr, int iif)
}
static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
- struct frag_hdr *fhdr, int nhoff)
+ struct frag_hdr *fhdr, int nhoff,
+ u32 *prob_offset)
{
struct sk_buff *prev, *next;
struct net_device *dev;
@@ -185,11 +186,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1)));
if ((unsigned int)end > IPV6_MAXPLEN) {
- __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
- IPSTATS_MIB_INHDRERRORS);
- icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
- ((u8 *)&fhdr->frag_off -
- skb_network_header(skb)));
+ *prob_offset = (u8 *)&fhdr->frag_off - skb_network_header(skb);
return -1;
}
@@ -220,10 +217,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
/* RFC2460 says always send parameter problem in
* this case. -DaveM
*/
- __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
- IPSTATS_MIB_INHDRERRORS);
- icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
- offsetof(struct ipv6hdr, payload_len));
+ *prob_offset = offsetof(struct ipv6hdr, payload_len);
return -1;
}
if (end > fq->q.len) {
@@ -524,15 +518,22 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
iif = skb->dev ? skb->dev->ifindex : 0;
fq = fq_find(net, fhdr->identification, hdr, iif);
if (fq) {
+ u32 prob_offset = 0;
int ret;
spin_lock(&fq->q.lock);
fq->iif = iif;
- ret = ip6_frag_queue(fq, skb, fhdr, IP6CB(skb)->nhoff);
+ ret = ip6_frag_queue(fq, skb, fhdr, IP6CB(skb)->nhoff,
+ &prob_offset);
spin_unlock(&fq->q.lock);
inet_frag_put(&fq->q);
+ if (prob_offset) {
+ __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
+ IPSTATS_MIB_INHDRERRORS);
+ icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, prob_offset);
+ }
return ret;
}
--
2.21.0.593.g511ec345e18-goog
next prev parent reply other threads:[~2019-04-26 15:41 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-26 15:41 [PATCH 4.9 stable 0/5] net: ip6 defrag: backport fixes Peter Oskolkov
2019-04-26 15:41 ` Peter Oskolkov [this message]
2019-04-26 15:41 ` [PATCH 4.9 stable 2/5] net: IP defrag: encapsulate rbtree defrag code into callable functions Peter Oskolkov
2019-04-26 15:41 ` [PATCH 4.9 stable 3/5] ipv6: remove dependency of nf_defrag_ipv6 on ipv6 module Peter Oskolkov
2019-04-26 15:41 ` [PATCH 4.9 stable 4/5] net: IP6 defrag: use rbtrees for IPv6 defrag Peter Oskolkov
2019-04-26 15:41 ` [PATCH 4.9 stable 5/5] net: IP6 defrag: use rbtrees in nf_conntrack_reasm.c Peter Oskolkov
2019-04-26 21:26 ` [PATCH 4.9 stable 0/5] net: ip6 defrag: backport fixes Peter Oskolkov
2019-04-29 16:54 ` Captain Wiggum
2019-04-27 1:02 ` Captain Wiggum
2019-04-29 16:57 ` Captain Wiggum
2019-04-29 17:23 ` Captain Wiggum
2019-04-29 17:31 ` Peter Oskolkov
2019-04-30 11:37 ` Greg Kroah-Hartman
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=20190426154108.52277-2-posk@google.com \
--to=posk@google.com \
--cc=captwiggum@gmail.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=gregkh@linuxfoundation.org \
--cc=lists@bofh.nu \
--cc=netdev@vger.kernel.org \
--cc=posk@posk.io \
--cc=sashal@kernel.org \
--cc=stable@vger.kernel.org \
/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.