netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next] net: sctp: sctp_set_owner_w: fix panic during skb orphaning
@ 2013-08-07 10:42 Daniel Borkmann
  2013-08-08  5:57 ` Neil Horman
  2013-08-09 20:37 ` David Miller
  0 siblings, 2 replies; 11+ messages in thread
From: Daniel Borkmann @ 2013-08-07 10:42 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-sctp

This patch fixes the following triggered bug ...

[  553.109742] kernel BUG at include/linux/skbuff.h:1813!
[  553.109766] invalid opcode: 0000 [#1] SMP
[  553.109789] Modules linked in: sctp libcrc32c rfcomm [...]
[  553.110259]  uinput i915 i2c_algo_bit drm_kms_helper e1000e drm ptp pps_core i2c_core wmi video sunrpc
[  553.110320] CPU: 0 PID: 1636 Comm: lt-test_1_to_1_ Not tainted 3.11.0-rc3+ #2
[  553.110350] Hardware name: LENOVO 74597D6/74597D6, BIOS 6DET60WW (3.10 ) 09/17/2009
[  553.110381] task: ffff88020a01dd40 ti: ffff880204ed0000 task.ti: ffff880204ed0000
[  553.110411] RIP: 0010:[<ffffffffa0698017>]  [<ffffffffa0698017>] skb_orphan.part.9+0x4/0x6 [sctp]
[  553.110459] RSP: 0018:ffff880204ed1bb8  EFLAGS: 00010286
[  553.110483] RAX: ffff8802086f5a40 RBX: ffff880204303300 RCX: 0000000000000000
[  553.110487] RDX: ffff880204303c28 RSI: ffff8802086f5a40 RDI: ffff880202158000
[  553.110487] RBP: ffff880204ed1bb8 R08: 0000000000000000 R09: 0000000000000000
[  553.110487] R10: ffff88022f2d9a04 R11: ffff880233001600 R12: 0000000000000000
[  553.110487] R13: ffff880204303c00 R14: ffff8802293d0000 R15: ffff880202158000
[  553.110487] FS:  00007f31b31fe740(0000) GS:ffff88023bc00000(0000) knlGS:0000000000000000
[  553.110487] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[  553.110487] CR2: 000000379980e3e0 CR3: 000000020d225000 CR4: 00000000000407f0
[  553.110487] Stack:
[  553.110487]  ffff880204ed1ca8 ffffffffa068d7fc 0000000000000000 0000000000000000
[  553.110487]  0000000000000000 ffff8802293d0000 ffff880202158000 ffffffff81cb7900
[  553.110487]  0000000000000000 0000400000001c68 ffff8802086f5a40 000000000000000f
[  553.110487] Call Trace:
[  553.110487]  [<ffffffffa068d7fc>] sctp_sendmsg+0x6bc/0xc80 [sctp]
[  553.110487]  [<ffffffff8128f185>] ? sock_has_perm+0x75/0x90
[  553.110487]  [<ffffffff815a3593>] inet_sendmsg+0x63/0xb0
[  553.110487]  [<ffffffff8128f2b3>] ? selinux_socket_sendmsg+0x23/0x30
[  553.110487]  [<ffffffff8151c5d6>] sock_sendmsg+0xa6/0xd0
[  553.110487]  [<ffffffff81637b05>] ? _raw_spin_unlock_bh+0x15/0x20
[  553.110487]  [<ffffffff8151cd38>] SYSC_sendto+0x128/0x180
[  553.110487]  [<ffffffff8151ce6b>] ? SYSC_connect+0xdb/0x100
[  553.110487]  [<ffffffffa0690031>] ? sctp_inet_listen+0x71/0x1f0 [sctp]
[  553.110487]  [<ffffffff8151d35e>] SyS_sendto+0xe/0x10
[  553.110487]  [<ffffffff81640202>] system_call_fastpath+0x16/0x1b
[  553.110487] Code: e0 48 c7 c7 00 22 6a a0 e8 67 a3 f0 e0 48 c7 [...]
[  553.110487] RIP  [<ffffffffa0698017>] skb_orphan.part.9+0x4/0x6 [sctp]
[  553.110487]  RSP <ffff880204ed1bb8>
[  553.121578] ---[ end trace 46c20c5903ef5be2 ]---

... that is triggered after commit 376c7311b ("net: add a temporary sanity
check in skb_orphan()"). What is happening is that we call sctp_set_owner_w()
for chunks in the SCTP output path from sctp_sendmsg(). Such chunks eventually
origin from constructors like sctp_make_chunk() where skb->sk = sk is being
set for socket accounting. Doing a git grep -n "skb->sk" net/sctp/ shows that
also in other places the socket pointer is being set, before issuing a
SCTP_CMD_SEND_PKT command and the like. Since SCTP is doing it's own memory
accounting anyway and has its own skb destructor functions, we should
customize sctp_set_owner_w() and call skb_orphan() if we set a different
owner of the skb than the current one in order to properly call their
destructor function, but not run into a panic due to our non-exisiting one as
we set sctp_wfree() destructor right after that. Otherwise, we can just skip
orphaning and reassignment to the very same socket and only set the destructor
handler.

Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
 Only in net-next.

 net/sctp/socket.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index d5d5882..7459b6c 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -153,13 +153,18 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk)
 {
 	struct sctp_association *asoc = chunk->asoc;
 	struct sock *sk = asoc->base.sk;
+	struct sk_buff *skb = chunk->skb;
 
 	/* The sndbuf space is tracked per association.  */
 	sctp_association_hold(asoc);
 
-	skb_set_owner_w(chunk->skb, sk);
+	if (skb->sk != sk) {
+		skb_orphan(skb);
+		skb->sk = sk;
+	}
+
+	skb->destructor = sctp_wfree;
 
-	chunk->skb->destructor = sctp_wfree;
 	/* Save the chunk pointer in skb for sctp_wfree to use later.  */
 	*((struct sctp_chunk **)(chunk->skb->cb)) = chunk;
 
@@ -167,9 +172,10 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk)
 				sizeof(struct sk_buff) +
 				sizeof(struct sctp_chunk);
 
-	atomic_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc);
-	sk->sk_wmem_queued += chunk->skb->truesize;
-	sk_mem_charge(sk, chunk->skb->truesize);
+	atomic_add(sizeof(struct sctp_chunk) + skb->truesize,
+		   &sk->sk_wmem_alloc);
+	sk->sk_wmem_queued += skb->truesize;
+	sk_mem_charge(sk, skb->truesize);
 }
 
 /* Verify that this is a valid address. */
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH net-next] net: sctp: sctp_set_owner_w: fix panic during skb orphaning
  2013-08-07 10:42 [PATCH net-next] net: sctp: sctp_set_owner_w: fix panic during skb orphaning Daniel Borkmann
@ 2013-08-08  5:57 ` Neil Horman
  2013-08-09 20:37 ` David Miller
  1 sibling, 0 replies; 11+ messages in thread
From: Neil Horman @ 2013-08-08  5:57 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: davem, netdev, linux-sctp

On Wed, Aug 07, 2013 at 12:42:01PM +0200, Daniel Borkmann wrote:
> This patch fixes the following triggered bug ...
> 
> [  553.109742] kernel BUG at include/linux/skbuff.h:1813!
> [  553.109766] invalid opcode: 0000 [#1] SMP
> [  553.109789] Modules linked in: sctp libcrc32c rfcomm [...]
> [  553.110259]  uinput i915 i2c_algo_bit drm_kms_helper e1000e drm ptp pps_core i2c_core wmi video sunrpc
> [  553.110320] CPU: 0 PID: 1636 Comm: lt-test_1_to_1_ Not tainted 3.11.0-rc3+ #2
> [  553.110350] Hardware name: LENOVO 74597D6/74597D6, BIOS 6DET60WW (3.10 ) 09/17/2009
> [  553.110381] task: ffff88020a01dd40 ti: ffff880204ed0000 task.ti: ffff880204ed0000
> [  553.110411] RIP: 0010:[<ffffffffa0698017>]  [<ffffffffa0698017>] skb_orphan.part.9+0x4/0x6 [sctp]
> [  553.110459] RSP: 0018:ffff880204ed1bb8  EFLAGS: 00010286
> [  553.110483] RAX: ffff8802086f5a40 RBX: ffff880204303300 RCX: 0000000000000000
> [  553.110487] RDX: ffff880204303c28 RSI: ffff8802086f5a40 RDI: ffff880202158000
> [  553.110487] RBP: ffff880204ed1bb8 R08: 0000000000000000 R09: 0000000000000000
> [  553.110487] R10: ffff88022f2d9a04 R11: ffff880233001600 R12: 0000000000000000
> [  553.110487] R13: ffff880204303c00 R14: ffff8802293d0000 R15: ffff880202158000
> [  553.110487] FS:  00007f31b31fe740(0000) GS:ffff88023bc00000(0000) knlGS:0000000000000000
> [  553.110487] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> [  553.110487] CR2: 000000379980e3e0 CR3: 000000020d225000 CR4: 00000000000407f0
> [  553.110487] Stack:
> [  553.110487]  ffff880204ed1ca8 ffffffffa068d7fc 0000000000000000 0000000000000000
> [  553.110487]  0000000000000000 ffff8802293d0000 ffff880202158000 ffffffff81cb7900
> [  553.110487]  0000000000000000 0000400000001c68 ffff8802086f5a40 000000000000000f
> [  553.110487] Call Trace:
> [  553.110487]  [<ffffffffa068d7fc>] sctp_sendmsg+0x6bc/0xc80 [sctp]
> [  553.110487]  [<ffffffff8128f185>] ? sock_has_perm+0x75/0x90
> [  553.110487]  [<ffffffff815a3593>] inet_sendmsg+0x63/0xb0
> [  553.110487]  [<ffffffff8128f2b3>] ? selinux_socket_sendmsg+0x23/0x30
> [  553.110487]  [<ffffffff8151c5d6>] sock_sendmsg+0xa6/0xd0
> [  553.110487]  [<ffffffff81637b05>] ? _raw_spin_unlock_bh+0x15/0x20
> [  553.110487]  [<ffffffff8151cd38>] SYSC_sendto+0x128/0x180
> [  553.110487]  [<ffffffff8151ce6b>] ? SYSC_connect+0xdb/0x100
> [  553.110487]  [<ffffffffa0690031>] ? sctp_inet_listen+0x71/0x1f0 [sctp]
> [  553.110487]  [<ffffffff8151d35e>] SyS_sendto+0xe/0x10
> [  553.110487]  [<ffffffff81640202>] system_call_fastpath+0x16/0x1b
> [  553.110487] Code: e0 48 c7 c7 00 22 6a a0 e8 67 a3 f0 e0 48 c7 [...]
> [  553.110487] RIP  [<ffffffffa0698017>] skb_orphan.part.9+0x4/0x6 [sctp]
> [  553.110487]  RSP <ffff880204ed1bb8>
> [  553.121578] ---[ end trace 46c20c5903ef5be2 ]---
> 
> ... that is triggered after commit 376c7311b ("net: add a temporary sanity
> check in skb_orphan()"). What is happening is that we call sctp_set_owner_w()
> for chunks in the SCTP output path from sctp_sendmsg(). Such chunks eventually
> origin from constructors like sctp_make_chunk() where skb->sk = sk is being
> set for socket accounting. Doing a git grep -n "skb->sk" net/sctp/ shows that
> also in other places the socket pointer is being set, before issuing a
> SCTP_CMD_SEND_PKT command and the like. Since SCTP is doing it's own memory
> accounting anyway and has its own skb destructor functions, we should
> customize sctp_set_owner_w() and call skb_orphan() if we set a different
> owner of the skb than the current one in order to properly call their
> destructor function, but not run into a panic due to our non-exisiting one as
> we set sctp_wfree() destructor right after that. Otherwise, we can just skip
> orphaning and reassignment to the very same socket and only set the destructor
> handler.
> 
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
> ---
>  Only in net-next.
> 
>  net/sctp/socket.c | 16 +++++++++++-----
>  1 file changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index d5d5882..7459b6c 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -153,13 +153,18 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk)
>  {
>  	struct sctp_association *asoc = chunk->asoc;
>  	struct sock *sk = asoc->base.sk;
> +	struct sk_buff *skb = chunk->skb;
>  
>  	/* The sndbuf space is tracked per association.  */
>  	sctp_association_hold(asoc);
>  
> -	skb_set_owner_w(chunk->skb, sk);
> +	if (skb->sk != sk) {
> +		skb_orphan(skb);
> +		skb->sk = sk;
> +	}
> +
> +	skb->destructor = sctp_wfree;
>  
> -	chunk->skb->destructor = sctp_wfree;
>  	/* Save the chunk pointer in skb for sctp_wfree to use later.  */
>  	*((struct sctp_chunk **)(chunk->skb->cb)) = chunk;
>  
> @@ -167,9 +172,10 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk)
>  				sizeof(struct sk_buff) +
>  				sizeof(struct sctp_chunk);
>  
> -	atomic_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc);
> -	sk->sk_wmem_queued += chunk->skb->truesize;
> -	sk_mem_charge(sk, chunk->skb->truesize);
> +	atomic_add(sizeof(struct sctp_chunk) + skb->truesize,
> +		   &sk->sk_wmem_alloc);
> +	sk->sk_wmem_queued += skb->truesize;
> +	sk_mem_charge(sk, skb->truesize);
>  }
>  
>  /* Verify that this is a valid address. */
> -- 
> 1.7.11.7
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
Acked-by: Neil Horman <nhorman@tuxdriver.com>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH net-next] net: sctp: sctp_set_owner_w: fix panic during skb orphaning
  2013-08-07 10:42 [PATCH net-next] net: sctp: sctp_set_owner_w: fix panic during skb orphaning Daniel Borkmann
  2013-08-08  5:57 ` Neil Horman
@ 2013-08-09 20:37 ` David Miller
  2013-08-09 20:47   ` Daniel Borkmann
  2013-08-09 21:58   ` [PATCH] net: sctp: fix panic during skb_orphan() Vlad Yasevich
  1 sibling, 2 replies; 11+ messages in thread
From: David Miller @ 2013-08-09 20:37 UTC (permalink / raw)
  To: dborkman; +Cc: netdev, linux-sctp

From: Daniel Borkmann <dborkman@redhat.com>
Date: Wed,  7 Aug 2013 12:42:01 +0200

> This patch fixes the following triggered bug ...
 ...
> ... that is triggered after commit 376c7311b ("net: add a temporary sanity
> check in skb_orphan()"). What is happening is that we call sctp_set_owner_w()
> for chunks in the SCTP output path from sctp_sendmsg(). Such chunks eventually
> origin from constructors like sctp_make_chunk() where skb->sk = sk is being
> set for socket accounting. Doing a git grep -n "skb->sk" net/sctp/ shows that
> also in other places the socket pointer is being set, before issuing a
> SCTP_CMD_SEND_PKT command and the like. Since SCTP is doing it's own memory
> accounting anyway and has its own skb destructor functions, we should
> customize sctp_set_owner_w() and call skb_orphan() if we set a different
> owner of the skb than the current one in order to properly call their
> destructor function, but not run into a panic due to our non-exisiting one as
> we set sctp_wfree() destructor right after that. Otherwise, we can just skip
> orphaning and reassignment to the very same socket and only set the destructor
> handler.

This debugging check is exactly trying to catch what SCTP is doing,
setting skb->sk without also setting the destructor.

I would much rather see you reorganize and fix SCTP to behave properly
rather than coding up a check which is essentially "if skb_orphan() bug
won't trigger, call it"  That defeats the whole purpose of the check.

Thanks.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH net-next] net: sctp: sctp_set_owner_w: fix panic during skb orphaning
  2013-08-09 20:37 ` David Miller
@ 2013-08-09 20:47   ` Daniel Borkmann
  2013-08-09 21:58   ` [PATCH] net: sctp: fix panic during skb_orphan() Vlad Yasevich
  1 sibling, 0 replies; 11+ messages in thread
From: Daniel Borkmann @ 2013-08-09 20:47 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-sctp

On 08/09/2013 10:37 PM, David Miller wrote:
> From: Daniel Borkmann <dborkman@redhat.com>
> Date: Wed,  7 Aug 2013 12:42:01 +0200
>
>> This patch fixes the following triggered bug ...
>   ...
>> ... that is triggered after commit 376c7311b ("net: add a temporary sanity
>> check in skb_orphan()"). What is happening is that we call sctp_set_owner_w()
>> for chunks in the SCTP output path from sctp_sendmsg(). Such chunks eventually
>> origin from constructors like sctp_make_chunk() where skb->sk = sk is being
>> set for socket accounting. Doing a git grep -n "skb->sk" net/sctp/ shows that
>> also in other places the socket pointer is being set, before issuing a
>> SCTP_CMD_SEND_PKT command and the like. Since SCTP is doing it's own memory
>> accounting anyway and has its own skb destructor functions, we should
>> customize sctp_set_owner_w() and call skb_orphan() if we set a different
>> owner of the skb than the current one in order to properly call their
>> destructor function, but not run into a panic due to our non-exisiting one as
>> we set sctp_wfree() destructor right after that. Otherwise, we can just skip
>> orphaning and reassignment to the very same socket and only set the destructor
>> handler.
>
> This debugging check is exactly trying to catch what SCTP is doing,
> setting skb->sk without also setting the destructor.
>
> I would much rather see you reorganize and fix SCTP to behave properly
> rather than coding up a check which is essentially "if skb_orphan() bug
> won't trigger, call it"  That defeats the whole purpose of the check.

Ok, will try to come up with a patch next week. Thanks.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH] net: sctp: fix panic during skb_orphan()
  2013-08-09 20:37 ` David Miller
  2013-08-09 20:47   ` Daniel Borkmann
@ 2013-08-09 21:58   ` Vlad Yasevich
  2013-08-09 23:20     ` Eric Dumazet
  1 sibling, 1 reply; 11+ messages in thread
From: Vlad Yasevich @ 2013-08-09 21:58 UTC (permalink / raw)
  To: netdev; +Cc: davem, linux-sctp, dborkman, Vlad Yasevich

This patch fixes the following triggered bug ...

[  553.109742] kernel BUG at include/linux/skbuff.h:1813!
[  553.109766] invalid opcode: 0000 [#1] SMP
[  553.109789] Modules linked in: sctp libcrc32c rfcomm [...]
[  553.110259]  uinput i915 i2c_algo_bit drm_kms_helper e1000e drm ptp
pps_core i2c_core wmi video sunrpc
[  553.110320] CPU: 0 PID: 1636 Comm: lt-test_1_to_1_ Not tainted
3.11.0-rc3+ #2
[  553.110350] Hardware name: LENOVO 74597D6/74597D6, BIOS 6DET60WW
(3.10 ) 09/17/2009
[  553.110381] task: ffff88020a01dd40 ti: ffff880204ed0000 task.ti:
ffff880204ed0000
[  553.110411] RIP: 0010:[<ffffffffa0698017>]  [<ffffffffa0698017>]
skb_orphan.part.9+0x4/0x6 [sctp]
[  553.110459] RSP: 0018:ffff880204ed1bb8  EFLAGS: 00010286
[  553.110483] RAX: ffff8802086f5a40 RBX: ffff880204303300 RCX:
0000000000000000
[  553.110487] RDX: ffff880204303c28 RSI: ffff8802086f5a40 RDI:
ffff880202158000
[  553.110487] RBP: ffff880204ed1bb8 R08: 0000000000000000 R09:
0000000000000000
[  553.110487] R10: ffff88022f2d9a04 R11: ffff880233001600 R12:
0000000000000000
[  553.110487] R13: ffff880204303c00 R14: ffff8802293d0000 R15:
ffff880202158000
[  553.110487] FS:  00007f31b31fe740(0000) GS:ffff88023bc00000(0000)
knlGS:0000000000000000
[  553.110487] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[  553.110487] CR2: 000000379980e3e0 CR3: 000000020d225000 CR4:
00000000000407f0
[  553.110487] Stack:
[  553.110487]  ffff880204ed1ca8 ffffffffa068d7fc 0000000000000000
0000000000000000
[  553.110487]  0000000000000000 ffff8802293d0000 ffff880202158000
ffffffff81cb7900
[  553.110487]  0000000000000000 0000400000001c68 ffff8802086f5a40
000000000000000f
[  553.110487] Call Trace:
[  553.110487]  [<ffffffffa068d7fc>] sctp_sendmsg+0x6bc/0xc80 [sctp]
[  553.110487]  [<ffffffff8128f185>] ? sock_has_perm+0x75/0x90
[  553.110487]  [<ffffffff815a3593>] inet_sendmsg+0x63/0xb0
[  553.110487]  [<ffffffff8128f2b3>] ? selinux_socket_sendmsg+0x23/0x30
[  553.110487]  [<ffffffff8151c5d6>] sock_sendmsg+0xa6/0xd0
[  553.110487]  [<ffffffff81637b05>] ? _raw_spin_unlock_bh+0x15/0x20
[  553.110487]  [<ffffffff8151cd38>] SYSC_sendto+0x128/0x180
[  553.110487]  [<ffffffff8151ce6b>] ? SYSC_connect+0xdb/0x100
[  553.110487]  [<ffffffffa0690031>] ? sctp_inet_listen+0x71/0x1f0
[sctp]
[  553.110487]  [<ffffffff8151d35e>] SyS_sendto+0xe/0x10
[  553.110487]  [<ffffffff81640202>] system_call_fastpath+0x16/0x1b
[  553.110487] Code: e0 48 c7 c7 00 22 6a a0 e8 67 a3 f0 e0 48 c7 [...]
[  553.110487] RIP  [<ffffffffa0698017>] skb_orphan.part.9+0x4/0x6
[sctp]
[  553.110487]  RSP <ffff880204ed1bb8>
[  553.121578] ---[ end trace 46c20c5903ef5be2 ]---

When a SCTP data chunk is created, skb->sk is set by sctp_make_chunk().
At a later time, sctp_sendmg() calls sctp_set_owner_w() which will attempt
to orphan the skb and correctly set the skb->sk.  The skb_orphan call result
in the above crash since skb->sk was set the the destructor was not.

The simple solution is to not set skb->sk for DATA chunks (since it
will be done later).  Continue to do it for control chunks since
sctp needs the sk at a later timer and control chunks are not currently
accouted agains socket memory.

Signed-off-by: Vlad Yasevich <vyasevich@gmail.com>
---
 net/sctp/sm_make_chunk.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 780a2d4..4ff7803 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1385,8 +1385,12 @@ static struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
 	if (sctp_auth_send_cid(type, asoc))
 		retval->auth = 1;
 
-	/* Set the skb to the belonging sock for accounting.  */
-	skb->sk = sk;
+	/* Set the skb to the belonging sock for accounting.  Do not
+	 * do this for data chunks as that will be properly set
+	 * up later.
+	 */
+	if (type != SCTP_CID_DATA)
+		skb->sk = sk;
 
 	return retval;
 nodata:
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH] net: sctp: fix panic during skb_orphan()
  2013-08-09 21:58   ` [PATCH] net: sctp: fix panic during skb_orphan() Vlad Yasevich
@ 2013-08-09 23:20     ` Eric Dumazet
  2013-08-10  0:39       ` Vlad Yasevich
  0 siblings, 1 reply; 11+ messages in thread
From: Eric Dumazet @ 2013-08-09 23:20 UTC (permalink / raw)
  To: Vlad Yasevich; +Cc: netdev, davem, linux-sctp, dborkman

On Fri, 2013-08-09 at 17:58 -0400, Vlad Yasevich wrote:
> This patch fixes the following triggered bug ...
> 
> [  553.109742] kernel BUG at include/linux/skbuff.h:1813!
> [  553.109766] invalid opcode: 0000 [#1] SMP
> [  553.109789] Modules linked in: sctp libcrc32c rfcomm [...]
> [  553.110259]  uinput i915 i2c_algo_bit drm_kms_helper e1000e drm ptp
> pps_core i2c_core wmi video sunrpc
> [  553.110320] CPU: 0 PID: 1636 Comm: lt-test_1_to_1_ Not tainted
> 3.11.0-rc3+ #2
> [  553.110350] Hardware name: LENOVO 74597D6/74597D6, BIOS 6DET60WW
> (3.10 ) 09/17/2009
> [  553.110381] task: ffff88020a01dd40 ti: ffff880204ed0000 task.ti:
> ffff880204ed0000
> [  553.110411] RIP: 0010:[<ffffffffa0698017>]  [<ffffffffa0698017>]
> skb_orphan.part.9+0x4/0x6 [sctp]
> [  553.110459] RSP: 0018:ffff880204ed1bb8  EFLAGS: 00010286
> [  553.110483] RAX: ffff8802086f5a40 RBX: ffff880204303300 RCX:
> 0000000000000000
> [  553.110487] RDX: ffff880204303c28 RSI: ffff8802086f5a40 RDI:
> ffff880202158000
> [  553.110487] RBP: ffff880204ed1bb8 R08: 0000000000000000 R09:
> 0000000000000000
> [  553.110487] R10: ffff88022f2d9a04 R11: ffff880233001600 R12:
> 0000000000000000
> [  553.110487] R13: ffff880204303c00 R14: ffff8802293d0000 R15:
> ffff880202158000
> [  553.110487] FS:  00007f31b31fe740(0000) GS:ffff88023bc00000(0000)
> knlGS:0000000000000000
> [  553.110487] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> [  553.110487] CR2: 000000379980e3e0 CR3: 000000020d225000 CR4:
> 00000000000407f0
> [  553.110487] Stack:
> [  553.110487]  ffff880204ed1ca8 ffffffffa068d7fc 0000000000000000
> 0000000000000000
> [  553.110487]  0000000000000000 ffff8802293d0000 ffff880202158000
> ffffffff81cb7900
> [  553.110487]  0000000000000000 0000400000001c68 ffff8802086f5a40
> 000000000000000f
> [  553.110487] Call Trace:
> [  553.110487]  [<ffffffffa068d7fc>] sctp_sendmsg+0x6bc/0xc80 [sctp]
> [  553.110487]  [<ffffffff8128f185>] ? sock_has_perm+0x75/0x90
> [  553.110487]  [<ffffffff815a3593>] inet_sendmsg+0x63/0xb0
> [  553.110487]  [<ffffffff8128f2b3>] ? selinux_socket_sendmsg+0x23/0x30
> [  553.110487]  [<ffffffff8151c5d6>] sock_sendmsg+0xa6/0xd0
> [  553.110487]  [<ffffffff81637b05>] ? _raw_spin_unlock_bh+0x15/0x20
> [  553.110487]  [<ffffffff8151cd38>] SYSC_sendto+0x128/0x180
> [  553.110487]  [<ffffffff8151ce6b>] ? SYSC_connect+0xdb/0x100
> [  553.110487]  [<ffffffffa0690031>] ? sctp_inet_listen+0x71/0x1f0
> [sctp]
> [  553.110487]  [<ffffffff8151d35e>] SyS_sendto+0xe/0x10
> [  553.110487]  [<ffffffff81640202>] system_call_fastpath+0x16/0x1b
> [  553.110487] Code: e0 48 c7 c7 00 22 6a a0 e8 67 a3 f0 e0 48 c7 [...]
> [  553.110487] RIP  [<ffffffffa0698017>] skb_orphan.part.9+0x4/0x6
> [sctp]
> [  553.110487]  RSP <ffff880204ed1bb8>
> [  553.121578] ---[ end trace 46c20c5903ef5be2 ]---
> 
> When a SCTP data chunk is created, skb->sk is set by sctp_make_chunk().
> At a later time, sctp_sendmg() calls sctp_set_owner_w() which will attempt
> to orphan the skb and correctly set the skb->sk.  The skb_orphan call result
> in the above crash since skb->sk was set the the destructor was not.
> 
> The simple solution is to not set skb->sk for DATA chunks (since it
> will be done later).  Continue to do it for control chunks since
> sctp needs the sk at a later timer and control chunks are not currently
> accouted agains socket memory.
> 
> Signed-off-by: Vlad Yasevich <vyasevich@gmail.com>
> ---
>  net/sctp/sm_make_chunk.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
> index 780a2d4..4ff7803 100644
> --- a/net/sctp/sm_make_chunk.c
> +++ b/net/sctp/sm_make_chunk.c
> @@ -1385,8 +1385,12 @@ static struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
>  	if (sctp_auth_send_cid(type, asoc))
>  		retval->auth = 1;
>  
> -	/* Set the skb to the belonging sock for accounting.  */
> -	skb->sk = sk;
> +	/* Set the skb to the belonging sock for accounting.  Do not
> +	 * do this for data chunks as that will be properly set
> +	 * up later.
> +	 */
> +	if (type != SCTP_CID_DATA)
> +		skb->sk = sk;
>  
>  	return retval;
>  nodata:

This is ugly IMHO.

Why not using a dummy destructor ?

And I guess this patch is for net-next ?

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] net: sctp: fix panic during skb_orphan()
  2013-08-09 23:20     ` Eric Dumazet
@ 2013-08-10  0:39       ` Vlad Yasevich
  2013-08-10  1:20         ` Eric Dumazet
  2013-08-10  2:05         ` [PATCH net-next] net: sctp: Add rudimentary infrastructure to account for control chunks Vlad Yasevich
  0 siblings, 2 replies; 11+ messages in thread
From: Vlad Yasevich @ 2013-08-10  0:39 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev, davem, linux-sctp, dborkman

On 08/09/2013 07:20 PM, Eric Dumazet wrote:
> On Fri, 2013-08-09 at 17:58 -0400, Vlad Yasevich wrote:
>> This patch fixes the following triggered bug ...
>>
>> [  553.109742] kernel BUG at include/linux/skbuff.h:1813!
>> [  553.109766] invalid opcode: 0000 [#1] SMP
>> [  553.109789] Modules linked in: sctp libcrc32c rfcomm [...]
>> [  553.110259]  uinput i915 i2c_algo_bit drm_kms_helper e1000e drm ptp
>> pps_core i2c_core wmi video sunrpc
>> [  553.110320] CPU: 0 PID: 1636 Comm: lt-test_1_to_1_ Not tainted
>> 3.11.0-rc3+ #2
>> [  553.110350] Hardware name: LENOVO 74597D6/74597D6, BIOS 6DET60WW
>> (3.10 ) 09/17/2009
>> [  553.110381] task: ffff88020a01dd40 ti: ffff880204ed0000 task.ti:
>> ffff880204ed0000
>> [  553.110411] RIP: 0010:[<ffffffffa0698017>]  [<ffffffffa0698017>]
>> skb_orphan.part.9+0x4/0x6 [sctp]
>> [  553.110459] RSP: 0018:ffff880204ed1bb8  EFLAGS: 00010286
>> [  553.110483] RAX: ffff8802086f5a40 RBX: ffff880204303300 RCX:
>> 0000000000000000
>> [  553.110487] RDX: ffff880204303c28 RSI: ffff8802086f5a40 RDI:
>> ffff880202158000
>> [  553.110487] RBP: ffff880204ed1bb8 R08: 0000000000000000 R09:
>> 0000000000000000
>> [  553.110487] R10: ffff88022f2d9a04 R11: ffff880233001600 R12:
>> 0000000000000000
>> [  553.110487] R13: ffff880204303c00 R14: ffff8802293d0000 R15:
>> ffff880202158000
>> [  553.110487] FS:  00007f31b31fe740(0000) GS:ffff88023bc00000(0000)
>> knlGS:0000000000000000
>> [  553.110487] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
>> [  553.110487] CR2: 000000379980e3e0 CR3: 000000020d225000 CR4:
>> 00000000000407f0
>> [  553.110487] Stack:
>> [  553.110487]  ffff880204ed1ca8 ffffffffa068d7fc 0000000000000000
>> 0000000000000000
>> [  553.110487]  0000000000000000 ffff8802293d0000 ffff880202158000
>> ffffffff81cb7900
>> [  553.110487]  0000000000000000 0000400000001c68 ffff8802086f5a40
>> 000000000000000f
>> [  553.110487] Call Trace:
>> [  553.110487]  [<ffffffffa068d7fc>] sctp_sendmsg+0x6bc/0xc80 [sctp]
>> [  553.110487]  [<ffffffff8128f185>] ? sock_has_perm+0x75/0x90
>> [  553.110487]  [<ffffffff815a3593>] inet_sendmsg+0x63/0xb0
>> [  553.110487]  [<ffffffff8128f2b3>] ? selinux_socket_sendmsg+0x23/0x30
>> [  553.110487]  [<ffffffff8151c5d6>] sock_sendmsg+0xa6/0xd0
>> [  553.110487]  [<ffffffff81637b05>] ? _raw_spin_unlock_bh+0x15/0x20
>> [  553.110487]  [<ffffffff8151cd38>] SYSC_sendto+0x128/0x180
>> [  553.110487]  [<ffffffff8151ce6b>] ? SYSC_connect+0xdb/0x100
>> [  553.110487]  [<ffffffffa0690031>] ? sctp_inet_listen+0x71/0x1f0
>> [sctp]
>> [  553.110487]  [<ffffffff8151d35e>] SyS_sendto+0xe/0x10
>> [  553.110487]  [<ffffffff81640202>] system_call_fastpath+0x16/0x1b
>> [  553.110487] Code: e0 48 c7 c7 00 22 6a a0 e8 67 a3 f0 e0 48 c7 [...]
>> [  553.110487] RIP  [<ffffffffa0698017>] skb_orphan.part.9+0x4/0x6
>> [sctp]
>> [  553.110487]  RSP <ffff880204ed1bb8>
>> [  553.121578] ---[ end trace 46c20c5903ef5be2 ]---
>>
>> When a SCTP data chunk is created, skb->sk is set by sctp_make_chunk().
>> At a later time, sctp_sendmg() calls sctp_set_owner_w() which will attempt
>> to orphan the skb and correctly set the skb->sk.  The skb_orphan call result
>> in the above crash since skb->sk was set the the destructor was not.
>>
>> The simple solution is to not set skb->sk for DATA chunks (since it
>> will be done later).  Continue to do it for control chunks since
>> sctp needs the sk at a later timer and control chunks are not currently
>> accouted agains socket memory.
>>
>> Signed-off-by: Vlad Yasevich <vyasevich@gmail.com>
>> ---
>>   net/sctp/sm_make_chunk.c | 8 ++++++--
>>   1 file changed, 6 insertions(+), 2 deletions(-)
>>
>> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
>> index 780a2d4..4ff7803 100644
>> --- a/net/sctp/sm_make_chunk.c
>> +++ b/net/sctp/sm_make_chunk.c
>> @@ -1385,8 +1385,12 @@ static struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
>>   	if (sctp_auth_send_cid(type, asoc))
>>   		retval->auth = 1;
>>
>> -	/* Set the skb to the belonging sock for accounting.  */
>> -	skb->sk = sk;
>> +	/* Set the skb to the belonging sock for accounting.  Do not
>> +	 * do this for data chunks as that will be properly set
>> +	 * up later.
>> +	 */
>> +	if (type != SCTP_CID_DATA)
>> +		skb->sk = sk;
>>
>>   	return retval;
>>   nodata:
>
> This is ugly IMHO.

Yes, it is a bit ugly.  The "proper" way is to do accounting for all 
SCTP chunks, but that is a much larger piece of work.

>
> Why not using a dummy destructor ?

It would just be useless once we do proper accounting for all chunks.
But, I'll send a different idea if this is just too ugly.

>
> And I guess this patch is for net-next ?
>

Yes, sorry...

Anyway. I'll send an less ugly alternative...

-vlad

>
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] net: sctp: fix panic during skb_orphan()
  2013-08-10  0:39       ` Vlad Yasevich
@ 2013-08-10  1:20         ` Eric Dumazet
  2013-08-10  1:34           ` Vlad Yasevich
  2013-08-10  2:05         ` [PATCH net-next] net: sctp: Add rudimentary infrastructure to account for control chunks Vlad Yasevich
  1 sibling, 1 reply; 11+ messages in thread
From: Eric Dumazet @ 2013-08-10  1:20 UTC (permalink / raw)
  To: Vlad Yasevich; +Cc: netdev, davem, linux-sctp, dborkman

On Fri, 2013-08-09 at 20:39 -0400, Vlad Yasevich wrote:
> On 08/09/2013 07:20 PM, Eric Dumazet wrote:

> > Why not using a dummy destructor ?
> 
> It would just be useless once we do proper accounting for all chunks.
> But, I'll send a different idea if this is just too ugly.

Setting skb->sk is no accounting.

It seems you would better use skb->cb[] so that you are 100% sure this
skb->sk doesn't leak outside of SCTP code.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] net: sctp: fix panic during skb_orphan()
  2013-08-10  1:20         ` Eric Dumazet
@ 2013-08-10  1:34           ` Vlad Yasevich
  0 siblings, 0 replies; 11+ messages in thread
From: Vlad Yasevich @ 2013-08-10  1:34 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev, davem, linux-sctp, dborkman

On 08/09/2013 09:20 PM, Eric Dumazet wrote:
> On Fri, 2013-08-09 at 20:39 -0400, Vlad Yasevich wrote:
>> On 08/09/2013 07:20 PM, Eric Dumazet wrote:
>
>>> Why not using a dummy destructor ?
>>
>> It would just be useless once we do proper accounting for all chunks.
>> But, I'll send a different idea if this is just too ugly.
>
> Setting skb->sk is no accounting.

Right.  It is only really used right now when constructing a packet to 
transmit out of a set of chunks.

>
> It seems you would better use skb->cb[] so that you are 100% sure this
> skb->sk doesn't leak outside of SCTP code.

Hmm..  That might work too.  I am building a framework right now that
we can use to add proper buffer accounting.  That's probably a better
long term solution.

-vlad

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH net-next] net: sctp: Add rudimentary infrastructure to account for control chunks
  2013-08-10  0:39       ` Vlad Yasevich
  2013-08-10  1:20         ` Eric Dumazet
@ 2013-08-10  2:05         ` Vlad Yasevich
  2013-08-13 22:04           ` David Miller
  1 sibling, 1 reply; 11+ messages in thread
From: Vlad Yasevich @ 2013-08-10  2:05 UTC (permalink / raw)
  To: netdev; +Cc: davem, linux-sctp, dborkman, eric.dumazet, Vlad Yasevich

This patch adds a base infrastructure that allows SCTP to do
memory accounting for control chunks.  Real accounting code will
follow.

This patch alos fixes the following triggered bug ...

[  553.109742] kernel BUG at include/linux/skbuff.h:1813!
[  553.109766] invalid opcode: 0000 [#1] SMP
[  553.109789] Modules linked in: sctp libcrc32c rfcomm [...]
[  553.110259]  uinput i915 i2c_algo_bit drm_kms_helper e1000e drm ptp
pps_core i2c_core wmi video sunrpc
[  553.110320] CPU: 0 PID: 1636 Comm: lt-test_1_to_1_ Not tainted
3.11.0-rc3+ #2
[  553.110350] Hardware name: LENOVO 74597D6/74597D6, BIOS 6DET60WW
(3.10 ) 09/17/2009
[  553.110381] task: ffff88020a01dd40 ti: ffff880204ed0000 task.ti:
ffff880204ed0000
[  553.110411] RIP: 0010:[<ffffffffa0698017>]  [<ffffffffa0698017>]
skb_orphan.part.9+0x4/0x6 [sctp]
[  553.110459] RSP: 0018:ffff880204ed1bb8  EFLAGS: 00010286
[  553.110483] RAX: ffff8802086f5a40 RBX: ffff880204303300 RCX:
0000000000000000
[  553.110487] RDX: ffff880204303c28 RSI: ffff8802086f5a40 RDI:
ffff880202158000
[  553.110487] RBP: ffff880204ed1bb8 R08: 0000000000000000 R09:
0000000000000000
[  553.110487] R10: ffff88022f2d9a04 R11: ffff880233001600 R12:
0000000000000000
[  553.110487] R13: ffff880204303c00 R14: ffff8802293d0000 R15:
ffff880202158000
[  553.110487] FS:  00007f31b31fe740(0000) GS:ffff88023bc00000(0000)
knlGS:0000000000000000
[  553.110487] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[  553.110487] CR2: 000000379980e3e0 CR3: 000000020d225000 CR4:
00000000000407f0
[  553.110487] Stack:
[  553.110487]  ffff880204ed1ca8 ffffffffa068d7fc 0000000000000000
0000000000000000
[  553.110487]  0000000000000000 ffff8802293d0000 ffff880202158000
ffffffff81cb7900
[  553.110487]  0000000000000000 0000400000001c68 ffff8802086f5a40
000000000000000f
[  553.110487] Call Trace:
[  553.110487]  [<ffffffffa068d7fc>] sctp_sendmsg+0x6bc/0xc80 [sctp]
[  553.110487]  [<ffffffff8128f185>] ? sock_has_perm+0x75/0x90
[  553.110487]  [<ffffffff815a3593>] inet_sendmsg+0x63/0xb0
[  553.110487]  [<ffffffff8128f2b3>] ? selinux_socket_sendmsg+0x23/0x30
[  553.110487]  [<ffffffff8151c5d6>] sock_sendmsg+0xa6/0xd0
[  553.110487]  [<ffffffff81637b05>] ? _raw_spin_unlock_bh+0x15/0x20
[  553.110487]  [<ffffffff8151cd38>] SYSC_sendto+0x128/0x180
[  553.110487]  [<ffffffff8151ce6b>] ? SYSC_connect+0xdb/0x100
[  553.110487]  [<ffffffffa0690031>] ? sctp_inet_listen+0x71/0x1f0
[sctp]
[  553.110487]  [<ffffffff8151d35e>] SyS_sendto+0xe/0x10
[  553.110487]  [<ffffffff81640202>] system_call_fastpath+0x16/0x1b
[  553.110487] Code: e0 48 c7 c7 00 22 6a a0 e8 67 a3 f0 e0 48 c7 [...]
[  553.110487] RIP  [<ffffffffa0698017>] skb_orphan.part.9+0x4/0x6
[sctp]
[  553.110487]  RSP <ffff880204ed1bb8>
[  553.121578] ---[ end trace 46c20c5903ef5be2 ]---

The approach taken here is to split data and control chunks
creation a  bit.  Data chunks already have memory accounting
so noting needs to happen.  For control chunks, add stubs handlers.

Signed-off-by: Vlad Yasevich <vyasevich@gmail.com>
---
 net/sctp/sm_make_chunk.c | 99 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 69 insertions(+), 30 deletions(-)

diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 780a2d4..04a82a6 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -68,8 +68,12 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
-static struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
-					  __u8 type, __u8 flags, int paylen);
+static struct sctp_chunk *sctp_make_control(const struct sctp_association *asoc,
+					    __u8 type, __u8 flags, int paylen);
+static struct sctp_chunk *sctp_make_data(const struct sctp_association *asoc,
+					 __u8 flags, int paylen);
+static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc,
+					   __u8 type, __u8 flags, int paylen);
 static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
 					const struct sctp_association *asoc,
 					const struct sctp_chunk *init_chunk,
@@ -82,6 +86,28 @@ static int sctp_process_param(struct sctp_association *asoc,
 static void *sctp_addto_param(struct sctp_chunk *chunk, int len,
 			      const void *data);
 
+/* Control chunk destructor */
+static void sctp_control_release_owner(struct sk_buff *skb)
+{
+	/*TODO: do memory release */
+}
+
+static void sctp_control_set_owner_w(struct sctp_chunk *chunk)
+{
+	struct sctp_association *asoc = chunk->asoc;
+	struct sk_buff *skb = chunk->skb;
+
+	/* TODO: properly account for control chunks. 
+	 * To do it right we'll need:
+	 *  1) endpoint if association isn't known.
+	 *  2) proper memory accounting.
+	 *
+	 *  For now don't do anything for now.
+	 */
+	skb->sk = asoc ? asoc->base.sk : NULL;
+	skb->destructor = sctp_control_release_owner;
+}
+
 /* What was the inbound interface for this chunk? */
 int sctp_chunk_iif(const struct sctp_chunk *chunk)
 {
@@ -296,7 +322,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
 	 * PLEASE DO NOT FIXME [This version does not support Host Name.]
 	 */
 
-	retval = sctp_make_chunk(asoc, SCTP_CID_INIT, 0, chunksize);
+	retval = sctp_make_control(asoc, SCTP_CID_INIT, 0, chunksize);
 	if (!retval)
 		goto nodata;
 
@@ -443,7 +469,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
 					num_ext);
 
 	/* Now allocate and fill out the chunk.  */
-	retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize);
+	retval = sctp_make_control(asoc, SCTP_CID_INIT_ACK, 0, chunksize);
 	if (!retval)
 		goto nomem_chunk;
 
@@ -548,7 +574,7 @@ struct sctp_chunk *sctp_make_cookie_echo(const struct sctp_association *asoc,
 	cookie_len = asoc->peer.cookie_len;
 
 	/* Build a cookie echo chunk.  */
-	retval = sctp_make_chunk(asoc, SCTP_CID_COOKIE_ECHO, 0, cookie_len);
+	retval = sctp_make_control(asoc, SCTP_CID_COOKIE_ECHO, 0, cookie_len);
 	if (!retval)
 		goto nodata;
 	retval->subh.cookie_hdr =
@@ -593,7 +619,7 @@ struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *asoc,
 {
 	struct sctp_chunk *retval;
 
-	retval = sctp_make_chunk(asoc, SCTP_CID_COOKIE_ACK, 0, 0);
+	retval = sctp_make_control(asoc, SCTP_CID_COOKIE_ACK, 0, 0);
 
 	/* RFC 2960 6.4 Multi-homed SCTP Endpoints
 	 *
@@ -641,8 +667,8 @@ struct sctp_chunk *sctp_make_cwr(const struct sctp_association *asoc,
 	sctp_cwrhdr_t cwr;
 
 	cwr.lowest_tsn = htonl(lowest_tsn);
-	retval = sctp_make_chunk(asoc, SCTP_CID_ECN_CWR, 0,
-				 sizeof(sctp_cwrhdr_t));
+	retval = sctp_make_control(asoc, SCTP_CID_ECN_CWR, 0,
+				   sizeof(sctp_cwrhdr_t));
 
 	if (!retval)
 		goto nodata;
@@ -675,8 +701,8 @@ struct sctp_chunk *sctp_make_ecne(const struct sctp_association *asoc,
 	sctp_ecnehdr_t ecne;
 
 	ecne.lowest_tsn = htonl(lowest_tsn);
-	retval = sctp_make_chunk(asoc, SCTP_CID_ECN_ECNE, 0,
-				 sizeof(sctp_ecnehdr_t));
+	retval = sctp_make_control(asoc, SCTP_CID_ECN_ECNE, 0,
+				   sizeof(sctp_ecnehdr_t));
 	if (!retval)
 		goto nodata;
 	retval->subh.ecne_hdr =
@@ -712,7 +738,7 @@ struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc,
 		dp.ssn = htons(ssn);
 
 	chunk_len = sizeof(dp) + data_len;
-	retval = sctp_make_chunk(asoc, SCTP_CID_DATA, flags, chunk_len);
+	retval = sctp_make_data(asoc, flags, chunk_len);
 	if (!retval)
 		goto nodata;
 
@@ -759,7 +785,7 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc)
 		+ sizeof(__u32) * num_dup_tsns;
 
 	/* Create the chunk.  */
-	retval = sctp_make_chunk(asoc, SCTP_CID_SACK, 0, len);
+	retval = sctp_make_control(asoc, SCTP_CID_SACK, 0, len);
 	if (!retval)
 		goto nodata;
 
@@ -838,8 +864,8 @@ struct sctp_chunk *sctp_make_shutdown(const struct sctp_association *asoc,
 	ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
 	shut.cum_tsn_ack = htonl(ctsn);
 
-	retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN, 0,
-				 sizeof(sctp_shutdownhdr_t));
+	retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN, 0,
+				   sizeof(sctp_shutdownhdr_t));
 	if (!retval)
 		goto nodata;
 
@@ -857,7 +883,7 @@ struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc,
 {
 	struct sctp_chunk *retval;
 
-	retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_ACK, 0, 0);
+	retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN_ACK, 0, 0);
 
 	/* RFC 2960 6.4 Multi-homed SCTP Endpoints
 	 *
@@ -886,7 +912,7 @@ struct sctp_chunk *sctp_make_shutdown_complete(
 	 */
 	flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T;
 
-	retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0);
+	retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0);
 
 	/* RFC 2960 6.4 Multi-homed SCTP Endpoints
 	 *
@@ -925,7 +951,7 @@ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc,
 			flags = SCTP_CHUNK_FLAG_T;
 	}
 
-	retval = sctp_make_chunk(asoc, SCTP_CID_ABORT, flags, hint);
+	retval = sctp_make_control(asoc, SCTP_CID_ABORT, flags, hint);
 
 	/* RFC 2960 6.4 Multi-homed SCTP Endpoints
 	 *
@@ -1117,7 +1143,7 @@ struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
 	struct sctp_chunk *retval;
 	sctp_sender_hb_info_t hbinfo;
 
-	retval = sctp_make_chunk(asoc, SCTP_CID_HEARTBEAT, 0, sizeof(hbinfo));
+	retval = sctp_make_control(asoc, SCTP_CID_HEARTBEAT, 0, sizeof(hbinfo));
 
 	if (!retval)
 		goto nodata;
@@ -1145,7 +1171,7 @@ struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *asoc,
 {
 	struct sctp_chunk *retval;
 
-	retval  = sctp_make_chunk(asoc, SCTP_CID_HEARTBEAT_ACK, 0, paylen);
+	retval  = sctp_make_control(asoc, SCTP_CID_HEARTBEAT_ACK, 0, paylen);
 	if (!retval)
 		goto nodata;
 
@@ -1177,8 +1203,8 @@ static struct sctp_chunk *sctp_make_op_error_space(
 {
 	struct sctp_chunk *retval;
 
-	retval = sctp_make_chunk(asoc, SCTP_CID_ERROR, 0,
-				 sizeof(sctp_errhdr_t) + size);
+	retval = sctp_make_control(asoc, SCTP_CID_ERROR, 0,
+				   sizeof(sctp_errhdr_t) + size);
 	if (!retval)
 		goto nodata;
 
@@ -1248,7 +1274,7 @@ struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc)
 	if (unlikely(!hmac_desc))
 		return NULL;
 
-	retval = sctp_make_chunk(asoc, SCTP_CID_AUTH, 0,
+	retval = sctp_make_control(asoc, SCTP_CID_AUTH, 0,
 			hmac_desc->hmac_len + sizeof(sctp_authhdr_t));
 	if (!retval)
 		return NULL;
@@ -1351,8 +1377,8 @@ const union sctp_addr *sctp_source(const struct sctp_chunk *chunk)
 /* Create a new chunk, setting the type and flags headers from the
  * arguments, reserving enough space for a 'paylen' byte payload.
  */
-static struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
-					  __u8 type, __u8 flags, int paylen)
+static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc,
+					    __u8 type, __u8 flags, int paylen)
 {
 	struct sctp_chunk *retval;
 	sctp_chunkhdr_t *chunk_hdr;
@@ -1385,14 +1411,27 @@ static struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
 	if (sctp_auth_send_cid(type, asoc))
 		retval->auth = 1;
 
-	/* Set the skb to the belonging sock for accounting.  */
-	skb->sk = sk;
-
 	return retval;
 nodata:
 	return NULL;
 }
 
+static struct sctp_chunk *sctp_make_data(const struct sctp_association *asoc,
+					 __u8 flags, int paylen)
+{
+	return _sctp_make_chunk(asoc, SCTP_CID_DATA, flags, paylen);
+}
+
+static struct sctp_chunk *sctp_make_control(const struct sctp_association *asoc,
+					    __u8 type, __u8 flags, int paylen)
+{
+	struct sctp_chunk *chunk = _sctp_make_chunk(asoc, type, flags, paylen);
+
+	if (chunk)
+		sctp_control_set_owner_w(chunk);
+
+	return chunk;
+}
 
 /* Release the memory occupied by a chunk.  */
 static void sctp_chunk_destroy(struct sctp_chunk *chunk)
@@ -2733,7 +2772,7 @@ static struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
 	length += addrlen;
 
 	/* Create the chunk.  */
-	retval = sctp_make_chunk(asoc, SCTP_CID_ASCONF, 0, length);
+	retval = sctp_make_control(asoc, SCTP_CID_ASCONF, 0, length);
 	if (!retval)
 		return NULL;
 
@@ -2917,7 +2956,7 @@ static struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association *as
 	int			length = sizeof(asconf) + vparam_len;
 
 	/* Create the chunk.  */
-	retval = sctp_make_chunk(asoc, SCTP_CID_ASCONF_ACK, 0, length);
+	retval = sctp_make_control(asoc, SCTP_CID_ASCONF_ACK, 0, length);
 	if (!retval)
 		return NULL;
 
@@ -3448,7 +3487,7 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
 
 	hint = (nstreams + 1) * sizeof(__u32);
 
-	retval = sctp_make_chunk(asoc, SCTP_CID_FWD_TSN, 0, hint);
+	retval = sctp_make_control(asoc, SCTP_CID_FWD_TSN, 0, hint);
 
 	if (!retval)
 		return NULL;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH net-next] net: sctp: Add rudimentary infrastructure to account for control chunks
  2013-08-10  2:05         ` [PATCH net-next] net: sctp: Add rudimentary infrastructure to account for control chunks Vlad Yasevich
@ 2013-08-13 22:04           ` David Miller
  0 siblings, 0 replies; 11+ messages in thread
From: David Miller @ 2013-08-13 22:04 UTC (permalink / raw)
  To: vyasevich; +Cc: netdev, linux-sctp, dborkman, eric.dumazet

From: Vlad Yasevich <vyasevich@gmail.com>
Date: Fri,  9 Aug 2013 22:05:36 -0400

> This patch adds a base infrastructure that allows SCTP to do
> memory accounting for control chunks.  Real accounting code will
> follow.
> 
> This patch alos fixes the following triggered bug ...
 ...
> The approach taken here is to split data and control chunks
> creation a  bit.  Data chunks already have memory accounting
> so noting needs to happen.  For control chunks, add stubs handlers.
> 
> Signed-off-by: Vlad Yasevich <vyasevich@gmail.com>

Applied, but:

> +	/* TODO: properly account for control chunks. 

I had to delete the trailing whitespace on that line.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2013-08-13 22:04 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-07 10:42 [PATCH net-next] net: sctp: sctp_set_owner_w: fix panic during skb orphaning Daniel Borkmann
2013-08-08  5:57 ` Neil Horman
2013-08-09 20:37 ` David Miller
2013-08-09 20:47   ` Daniel Borkmann
2013-08-09 21:58   ` [PATCH] net: sctp: fix panic during skb_orphan() Vlad Yasevich
2013-08-09 23:20     ` Eric Dumazet
2013-08-10  0:39       ` Vlad Yasevich
2013-08-10  1:20         ` Eric Dumazet
2013-08-10  1:34           ` Vlad Yasevich
2013-08-10  2:05         ` [PATCH net-next] net: sctp: Add rudimentary infrastructure to account for control chunks Vlad Yasevich
2013-08-13 22:04           ` 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).