diff mbox

[xfrm_user] BUG: sleeping function called from invalid context

Message ID 20100813153658.GA27982@gondor.apana.org.au
State Accepted, archived
Delegated to: David Miller
Headers show

Commit Message

Herbert Xu Aug. 13, 2010, 3:36 p.m. UTC
Luca Tettamanti <kronos.it@gmail.com> wrote:
>
> xfrm_user_policy takes read_lock(&xfrm_km_lock) before calling
> xfrm_compile_policy (via km->compile_policy), which in turn calls
> xfrm_policy_alloc with GFP_KERNEL.

Thanks for discovering this bug, it only took 8 years :)

xfrm: Use GFP_ATOMIC in xfrm_compile_policy

As xfrm_compile_policy runs within a read_lock, we cannot use
GFP_KERNEL for memory allocations.

Reported-by: Luca Tettamanti <kronos.it@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>


Cheers,

Comments

David Miller Aug. 15, 2010, 5:38 a.m. UTC | #1
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Fri, 13 Aug 2010 11:36:58 -0400

> Luca Tettamanti <kronos.it@gmail.com> wrote:
>>
>> xfrm_user_policy takes read_lock(&xfrm_km_lock) before calling
>> xfrm_compile_policy (via km->compile_policy), which in turn calls
>> xfrm_policy_alloc with GFP_KERNEL.
> 
> Thanks for discovering this bug, it only took 8 years :)

We stumble over one of these every so often don't we? :)

> 
> xfrm: Use GFP_ATOMIC in xfrm_compile_policy
> 
> As xfrm_compile_policy runs within a read_lock, we cannot use
> GFP_KERNEL for memory allocations.
> 
> Reported-by: Luca Tettamanti <kronos.it@gmail.com>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied, thanks Herbert.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index ba59983..b14ed4b 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2504,7 +2504,7 @@  static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
 	if (p->dir > XFRM_POLICY_OUT)
 		return NULL;
 
-	xp = xfrm_policy_alloc(net, GFP_KERNEL);
+	xp = xfrm_policy_alloc(net, GFP_ATOMIC);
 	if (xp == NULL) {
 		*dir = -ENOBUFS;
 		return NULL;