* [PATCH 1/2] xfrm: Force a dst refcount before entering the xfrm type handlers
@ 2011-03-16 7:08 Steffen Klassert
2011-03-16 7:09 ` [PATCH 2/2] dst: Clone child entry in skb_dst_pop Steffen Klassert
2011-03-16 7:17 ` [PATCH 1/2] xfrm: Force a dst refcount before entering the xfrm type handlers David Miller
0 siblings, 2 replies; 5+ messages in thread
From: Steffen Klassert @ 2011-03-16 7:08 UTC (permalink / raw)
To: David Miller, Eric Dumazet; +Cc: netdev
Crypto requests might return asynchronous. In this case we leave
the rcu protected region, so force a refcount on the skb's
destination entry before we enter the xfrm type input/output
handlers.
This fixes a crash when a route is deleted whilst sending IPsec
data that is transformed by an asynchronous algorithm.
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
net/xfrm/xfrm_input.c | 2 ++
net/xfrm/xfrm_output.c | 2 ++
2 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 872065c..341cd11 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -190,6 +190,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
XFRM_SKB_CB(skb)->seq.input.low = seq;
XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;
+ skb_dst_force(skb);
+
nexthdr = x->type->input(x, skb);
if (nexthdr == -EINPROGRESS)
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 1aba03f..8f3f0ee 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -78,6 +78,8 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
spin_unlock_bh(&x->lock);
+ skb_dst_force(skb);
+
err = x->type->output(x, skb);
if (err == -EINPROGRESS)
goto out_exit;
--
1.7.0.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] dst: Clone child entry in skb_dst_pop
2011-03-16 7:08 [PATCH 1/2] xfrm: Force a dst refcount before entering the xfrm type handlers Steffen Klassert
@ 2011-03-16 7:09 ` Steffen Klassert
2011-03-16 7:17 ` [PATCH 1/2] xfrm: Force a dst refcount before entering the xfrm type handlers David Miller
1 sibling, 0 replies; 5+ messages in thread
From: Steffen Klassert @ 2011-03-16 7:09 UTC (permalink / raw)
To: David Miller, Eric Dumazet; +Cc: netdev
We clone the child entry in skb_dst_pop before we call
skb_dst_drop(). Otherwise we might kill the child right
before we return it to the caller.
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
include/net/dst.h | 2 +-
net/xfrm/xfrm_output.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index 2a46cba..75b95df 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -345,7 +345,7 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb)
{
- struct dst_entry *child = skb_dst(skb)->child;
+ struct dst_entry *child = dst_clone(skb_dst(skb)->child);
skb_dst_drop(skb);
return child;
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 8f3f0ee..47bacd8 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -96,7 +96,7 @@ resume:
err = -EHOSTUNREACH;
goto error_nolock;
}
- skb_dst_set(skb, dst_clone(dst));
+ skb_dst_set(skb, dst);
x = dst->xfrm;
} while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL));
--
1.7.0.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] xfrm: Force a dst refcount before entering the xfrm type handlers
2011-03-16 7:08 [PATCH 1/2] xfrm: Force a dst refcount before entering the xfrm type handlers Steffen Klassert
2011-03-16 7:09 ` [PATCH 2/2] dst: Clone child entry in skb_dst_pop Steffen Klassert
@ 2011-03-16 7:17 ` David Miller
2011-03-16 7:43 ` Steffen Klassert
1 sibling, 1 reply; 5+ messages in thread
From: David Miller @ 2011-03-16 7:17 UTC (permalink / raw)
To: steffen.klassert; +Cc: eric.dumazet, netdev
Steffen we really need to find another way to fix these problems.
We already make way too many expensive atomic operations in these code
paths modified by your 3 patches, we should strive to not add new
ones.
Thanks.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] xfrm: Force a dst refcount before entering the xfrm type handlers
2011-03-16 7:17 ` [PATCH 1/2] xfrm: Force a dst refcount before entering the xfrm type handlers David Miller
@ 2011-03-16 7:43 ` Steffen Klassert
2011-03-16 17:41 ` David Miller
0 siblings, 1 reply; 5+ messages in thread
From: Steffen Klassert @ 2011-03-16 7:43 UTC (permalink / raw)
To: David Miller; +Cc: eric.dumazet, netdev
On Wed, Mar 16, 2011 at 12:17:32AM -0700, David Miller wrote:
>
> Steffen we really need to find another way to fix these problems.
>
> We already make way too many expensive atomic operations in these code
> paths modified by your 3 patches, we should strive to not add new
> ones.
>
I know that it is exspensive, but we have to take a refcount if
the crypto layer returns asyncronous. Unfortunately it is too
late to take the refcount when the crypto layer notifies us about
that as the skb might be already gone.
The second patch just moves the refcount from xfrm_output_one
to skb_dst_pop. As xfrm_output_one is the only user of
skb_dst_pop, we take the refcont just a bit realier.
The third one makes the socket policy case consistent to the
case where we get the destination entry from the flow cache
where we take a reference. We can either return the dst entry
with or without a refcont in both cases. But we can't return
sometimes with and somtimes without a refcount.
I'd be happy to see all these refcounts gone too of course,
but that's way beyond a simple bug fix.
Steffen
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] xfrm: Force a dst refcount before entering the xfrm type handlers
2011-03-16 7:43 ` Steffen Klassert
@ 2011-03-16 17:41 ` David Miller
0 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2011-03-16 17:41 UTC (permalink / raw)
To: steffen.klassert; +Cc: eric.dumazet, netdev
From: Steffen Klassert <steffen.klassert@secunet.com>
Date: Wed, 16 Mar 2011 08:43:06 +0100
> On Wed, Mar 16, 2011 at 12:17:32AM -0700, David Miller wrote:
>>
>> Steffen we really need to find another way to fix these problems.
>>
>> We already make way too many expensive atomic operations in these code
>> paths modified by your 3 patches, we should strive to not add new
>> ones.
>>
>
> I know that it is exspensive, but we have to take a refcount if
> the crypto layer returns asyncronous. Unfortunately it is too
> late to take the refcount when the crypto layer notifies us about
> that as the skb might be already gone.
We can pass around an atomic_t for the crypto layer to bump when
it decides to take an async path, bump it on entry and upon event
wakeup decrement it.
Actually, a plain atomic_t is a bad idea because we might have to
release the object. So callbacks with private void pointer arg is
better.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-03-16 17:40 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-16 7:08 [PATCH 1/2] xfrm: Force a dst refcount before entering the xfrm type handlers Steffen Klassert
2011-03-16 7:09 ` [PATCH 2/2] dst: Clone child entry in skb_dst_pop Steffen Klassert
2011-03-16 7:17 ` [PATCH 1/2] xfrm: Force a dst refcount before entering the xfrm type handlers David Miller
2011-03-16 7:43 ` Steffen Klassert
2011-03-16 17:41 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).