netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net 0/2] sctp: fix a NULL pointer dereference in sctp_sched_dequeue_common
@ 2022-11-04 21:45 Xin Long
  2022-11-04 21:45 ` [PATCH net 1/2] sctp: remove the unnecessary sinfo_stream check in sctp_prsctp_prune_unsent Xin Long
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Xin Long @ 2022-11-04 21:45 UTC (permalink / raw)
  To: network dev, linux-sctp
  Cc: davem, kuba, Eric Dumazet, Paolo Abeni, Marcelo Ricardo Leitner,
	Neil Horman, chenzhen126, caowangbao

This issue was triggered with SCTP_PR_SCTP_PRIO in sctp,
and caused by not checking and fixing stream->out_curr
after removing a chunk from this stream.

Patch 1 removes an unnecessary check and makes the real
fix easier to add in Patch 2.

Xin Long (2):
  sctp: remove the unnecessary sinfo_stream check in
    sctp_prsctp_prune_unsent
  sctp: clear out_curr if all frag chunks of current msg are pruned

 net/sctp/outqueue.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

-- 
2.31.1


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

* [PATCH net 1/2] sctp: remove the unnecessary sinfo_stream check in sctp_prsctp_prune_unsent
  2022-11-04 21:45 [PATCH net 0/2] sctp: fix a NULL pointer dereference in sctp_sched_dequeue_common Xin Long
@ 2022-11-04 21:45 ` Xin Long
  2022-11-04 21:45 ` [PATCH net 2/2] sctp: clear out_curr if all frag chunks of current msg are pruned Xin Long
  2022-11-08  4:10 ` [PATCH net 0/2] sctp: fix a NULL pointer dereference in sctp_sched_dequeue_common patchwork-bot+netdevbpf
  2 siblings, 0 replies; 4+ messages in thread
From: Xin Long @ 2022-11-04 21:45 UTC (permalink / raw)
  To: network dev, linux-sctp
  Cc: davem, kuba, Eric Dumazet, Paolo Abeni, Marcelo Ricardo Leitner,
	Neil Horman, chenzhen126, caowangbao

Since commit 5bbbbe32a431 ("sctp: introduce stream scheduler foundations"),
sctp_stream_outq_migrate() has been called in sctp_stream_init/update to
removes those chunks to streams higher than the new max. There is no longer
need to do such check in sctp_prsctp_prune_unsent().

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/sctp/outqueue.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index e213aaf45d67..c99fe3dc19bc 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -384,6 +384,7 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
 {
 	struct sctp_outq *q = &asoc->outqueue;
 	struct sctp_chunk *chk, *temp;
+	struct sctp_stream_out *sout;
 
 	q->sched->unsched_all(&asoc->stream);
 
@@ -398,12 +399,9 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
 		sctp_sched_dequeue_common(q, chk);
 		asoc->sent_cnt_removable--;
 		asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
-		if (chk->sinfo.sinfo_stream < asoc->stream.outcnt) {
-			struct sctp_stream_out *streamout =
-				SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream);
 
-			streamout->ext->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
-		}
+		sout = SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream);
+		sout->ext->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
 
 		msg_len -= chk->skb->truesize + sizeof(struct sctp_chunk);
 		sctp_chunk_free(chk);
-- 
2.31.1


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

* [PATCH net 2/2] sctp: clear out_curr if all frag chunks of current msg are pruned
  2022-11-04 21:45 [PATCH net 0/2] sctp: fix a NULL pointer dereference in sctp_sched_dequeue_common Xin Long
  2022-11-04 21:45 ` [PATCH net 1/2] sctp: remove the unnecessary sinfo_stream check in sctp_prsctp_prune_unsent Xin Long
@ 2022-11-04 21:45 ` Xin Long
  2022-11-08  4:10 ` [PATCH net 0/2] sctp: fix a NULL pointer dereference in sctp_sched_dequeue_common patchwork-bot+netdevbpf
  2 siblings, 0 replies; 4+ messages in thread
From: Xin Long @ 2022-11-04 21:45 UTC (permalink / raw)
  To: network dev, linux-sctp
  Cc: davem, kuba, Eric Dumazet, Paolo Abeni, Marcelo Ricardo Leitner,
	Neil Horman, chenzhen126, caowangbao

A crash was reported by Zhen Chen:

  list_del corruption, ffffa035ddf01c18->next is NULL
  WARNING: CPU: 1 PID: 250682 at lib/list_debug.c:49 __list_del_entry_valid+0x59/0xe0
  RIP: 0010:__list_del_entry_valid+0x59/0xe0
  Call Trace:
   sctp_sched_dequeue_common+0x17/0x70 [sctp]
   sctp_sched_fcfs_dequeue+0x37/0x50 [sctp]
   sctp_outq_flush_data+0x85/0x360 [sctp]
   sctp_outq_uncork+0x77/0xa0 [sctp]
   sctp_cmd_interpreter.constprop.0+0x164/0x1450 [sctp]
   sctp_side_effects+0x37/0xe0 [sctp]
   sctp_do_sm+0xd0/0x230 [sctp]
   sctp_primitive_SEND+0x2f/0x40 [sctp]
   sctp_sendmsg_to_asoc+0x3fa/0x5c0 [sctp]
   sctp_sendmsg+0x3d5/0x440 [sctp]
   sock_sendmsg+0x5b/0x70

and in sctp_sched_fcfs_dequeue() it dequeued a chunk from stream
out_curr outq while this outq was empty.

Normally stream->out_curr must be set to NULL once all frag chunks of
current msg are dequeued, as we can see in sctp_sched_dequeue_done().
However, in sctp_prsctp_prune_unsent() as it is not a proper dequeue,
sctp_sched_dequeue_done() is not called to do this.

This patch is to fix it by simply setting out_curr to NULL when the
last frag chunk of current msg is dequeued from out_curr stream in
sctp_prsctp_prune_unsent().

Fixes: 5bbbbe32a431 ("sctp: introduce stream scheduler foundations")
Reported-by: Zhen Chen <chenzhen126@huawei.com>
Tested-by: Caowangbao <caowangbao@huawei.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/sctp/outqueue.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index c99fe3dc19bc..20831079fb09 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -403,6 +403,11 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
 		sout = SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream);
 		sout->ext->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
 
+		/* clear out_curr if all frag chunks are pruned */
+		if (asoc->stream.out_curr == sout &&
+		    list_is_last(&chk->frag_list, &chk->msg->chunks))
+			asoc->stream.out_curr = NULL;
+
 		msg_len -= chk->skb->truesize + sizeof(struct sctp_chunk);
 		sctp_chunk_free(chk);
 		if (msg_len <= 0)
-- 
2.31.1


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

* Re: [PATCH net 0/2] sctp: fix a NULL pointer dereference in sctp_sched_dequeue_common
  2022-11-04 21:45 [PATCH net 0/2] sctp: fix a NULL pointer dereference in sctp_sched_dequeue_common Xin Long
  2022-11-04 21:45 ` [PATCH net 1/2] sctp: remove the unnecessary sinfo_stream check in sctp_prsctp_prune_unsent Xin Long
  2022-11-04 21:45 ` [PATCH net 2/2] sctp: clear out_curr if all frag chunks of current msg are pruned Xin Long
@ 2022-11-08  4:10 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 4+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-11-08  4:10 UTC (permalink / raw)
  To: Xin Long
  Cc: netdev, linux-sctp, davem, kuba, edumazet, pabeni,
	marcelo.leitner, nhorman, chenzhen126, caowangbao

Hello:

This series was applied to netdev/net.git (master)
by Jakub Kicinski <kuba@kernel.org>:

On Fri,  4 Nov 2022 17:45:14 -0400 you wrote:
> This issue was triggered with SCTP_PR_SCTP_PRIO in sctp,
> and caused by not checking and fixing stream->out_curr
> after removing a chunk from this stream.
> 
> Patch 1 removes an unnecessary check and makes the real
> fix easier to add in Patch 2.
> 
> [...]

Here is the summary with links:
  - [net,1/2] sctp: remove the unnecessary sinfo_stream check in sctp_prsctp_prune_unsent
    https://git.kernel.org/netdev/net/c/9f0b773210c2
  - [net,2/2] sctp: clear out_curr if all frag chunks of current msg are pruned
    https://git.kernel.org/netdev/net/c/2f201ae14ae0

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

end of thread, other threads:[~2022-11-08  4:10 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-11-04 21:45 [PATCH net 0/2] sctp: fix a NULL pointer dereference in sctp_sched_dequeue_common Xin Long
2022-11-04 21:45 ` [PATCH net 1/2] sctp: remove the unnecessary sinfo_stream check in sctp_prsctp_prune_unsent Xin Long
2022-11-04 21:45 ` [PATCH net 2/2] sctp: clear out_curr if all frag chunks of current msg are pruned Xin Long
2022-11-08  4:10 ` [PATCH net 0/2] sctp: fix a NULL pointer dereference in sctp_sched_dequeue_common patchwork-bot+netdevbpf

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).