NetBSD Problem Report #58708

From www@netbsd.org  Sun Sep 29 04:13:56 2024
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
	 client-signature RSA-PSS (2048 bits) client-digest SHA256)
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 089D81A923B
	for <gnats-bugs@gnats.NetBSD.org>; Sun, 29 Sep 2024 04:13:56 +0000 (UTC)
Message-Id: <20240929041354.972F51A923D@mollari.NetBSD.org>
Date: Sun, 29 Sep 2024 04:13:54 +0000 (UTC)
From: rin@iij.ad.jp
Reply-To: rin@iij.ad.jp
To: gnats-bugs@NetBSD.org
Subject: Mitigation for CVE-2018-6922 (SegmentSmack)
X-Send-Pr-Version: www-1.0

>Number:         58708
>Category:       security
>Synopsis:       Mitigation for CVE-2018-6922 (SegmentSmack)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    security-officer
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Sep 29 04:15:01 +0000 2024
>Closed-Date:    Wed Oct 09 15:09:56 +0000 2024
>Last-Modified:  Wed Oct 09 15:09:56 +0000 2024
>Originator:     Rin Okuyama
>Release:        HEAD, netbsd-10, and netbsd-9
>Organization:
Internet Initiative Japan Inc.
>Environment:
NetBSD lx2k 10.99.12 NetBSD 10.99.12 (GENERIC64) #0: Fri Sep 27 19:32:56 JST 2024  rin@sakaizumii.local:/home/rin/src/sys/arch/evbarm/compile/obj.evbarm-aarch64/GENERIC64 evbarm aarch64
>Description:
Abstract
========

Reassembling fragmented TCP segments in the traditional BSD network
stack has been implemented by using queues, which require CPU time
O(# of segments) for searching.

This allows attackers to send fine-grained fragmented segments to
realize the site-local DoS, which has been known as CVE-2018-6922
(SegmentSmack) [0].

FreeBSD published FreeBSD-SA-18:08.tcp [1] back to 2018, however,
unfortunately, this vulnerability has been left untouched for NetBSD
over six years.

Technical Details
=================

The length of TCP reassembly queue can be proportional to the receive
buffer (32KB by default, and automatically scaled up to 256KB).

An attacker can send fine-grained fragmented segments, say, segments
with even sequence numbers (0, 2, 4, ...) and 1-byte payload each.
This ends up with a queue with length ~ 128K. Then, the attacker
send another segments with large sequence numbers. For each segment,
the queue is linearly searched, which results in O(128K) CPU time
consumption.

This can be the site-local DoS; Tomoyuki Sahara <tsahara@iij.ad.jp>
carried out experiments with a netbsd-10/amd64 target. With
increasing attacker threads, console response from the target gets
delayed. And finally, with, say, three threads, it becomes
nonresponding to console.

Note that this worst scenario may be difficult in practice:

- Attackers need to increase TCP receive buffer (by auto-rescaling)
  before attack.

- The TCP stack or applications may be timed-out before attack is
  achieved.

[0] https://nvd.nist.gov/vuln/detail/CVE-2018-6922

[1] https://www.freebsd.org/security/advisories/FreeBSD-SA-18:08.tcp.asc
>How-To-Repeat:
Pseudo-code for attackers is provided by T. Sahara [2]. Note that
logic for rescaling receive buffer is missing in this code.

[2] Ruby-styled pseudo-code for attackers is as follows.
````
  3.times { |hostnum|
    h = Host.new(eth0: "172.16.0.3#{hostnum}")
    t = TCP::Client.new(host: h, dstip: "172.16.0.9", dstport: 23,
                        do_sack: true)
    def t.on_established
      t = self
      200000.times { |i|
        if i < 16000
          k = t.seq + 2*i
        else
          k = t.seq + 31990
        end
        t.send_tcp_packet(payload: "a", seq: k)
        Scheduler.sleep 1e-3
      }
    end
  }
````
>Fix:
Solutions
=========

A mitigation at a level of FreeBSD [3], was originally implemented
by Ryo Shimizu, and updated by T. Sahara [4].

This mitigation introduces an arbitrary (100) limit to the length of
TCP reassembly queues. As a result, maliciously fragmented segments,
as described above, are dropped to avoid CPU time consumption.

This reduces CPU time per packet from O(128K) to O(100), however,
still, this only mitigates the problem. The real fix should be to
reimplement the TCP reassembly routines. For instance, we may use
rbtrees instead of queues. This has not yet been examined at all.

Thanks to
=========

The mitigation was originally implemented by Ryo Shimizu. T. Sahara
updated it. He also analyzed the problem, and carried out experiments
for the vulnerability scenario. This PR is mostly based on his works,
modulo the ambiguity added by myself.

[3] https://github.com/freebsd/freebsd-src/commit/95a914f6316874f5b0c45d491f2843dc810071ef

[4] This diff has been compile-tested for amd64/aarch64 with gcc/clang
    for -HEAD/netbsd-10. No new regression observed for full ATF runs
    on amd64/aarch64 with/without NET_MPSAFE and LOCKDEBUG (for kernel
    and rump kernel).
````
--- sys/netinet/tcp_input.c
+++ sys/netinet/tcp_input.c
@@ -231,6 +231,8 @@ int	tcp_autorcvbuf_inc = 16 * 1024;
 int	tcp_autorcvbuf_max = 256 * 1024;
 int	tcp_msl = (TCPTV_MSL / PR_SLOWHZ);

+int tcp_reass_maxqueuelen = 100;
+
 static int tcp_rst_ppslim_count = 0;
 static struct timeval tcp_rst_ppslim_last;
 static int tcp_ackdrop_ppslim_count = 0;
@@ -707,6 +709,13 @@ tcp_reass(struct tcpcb *tp, const struct tcphdr *th, struct mbuf *m, int tlen)
 #endif

 insert_it:
+	/* limit tcp segments per reassembly queue */
+	if (tp->t_segqlen > tcp_reass_maxqueuelen) {
+		TCP_STATINC(TCP_STAT_RCVMEMDROP);
+		m_freem(m);
+		goto out;
+	}
+
 	/*
 	 * Allocate a new queue entry (block) since the received segment
 	 * did not collapse onto any other out-of-order block. If it had
````

>Release-Note:

>Audit-Trail:
From: Rin Okuyama <rokuyama.rk@gmail.com>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: security/58708: Mitigation for CVE-2018-6922 (SegmentSmack)
Date: Fri, 4 Oct 2024 22:41:57 +0900

 Can someone review/comment on diff? Or can I just commit and
 request pullup to netbsd-{10,9} immediately?

 Thanks,
 rin

From: "Rin Okuyama" <rin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/58708 CVS commit: src/sys/netinet
Date: Tue, 8 Oct 2024 06:17:14 +0000

 Module Name:	src
 Committed By:	rin
 Date:		Tue Oct  8 06:17:14 UTC 2024

 Modified Files:
 	src/sys/netinet: tcp_input.c

 Log Message:
 tcp_reass: Mitigate CVE-2018-6922 (SegmentSmack)

 at a level of FreeBSD, by introducing an arbitrary (100) limit to
 the length of TCP reassembly queues:

 https://github.com/freebsd/freebsd-src/commit/95a914f6316874f5b0c45d491f2843dc810071ef

 Originally authored by ryo@.

 We thank Tomoyuki Sahara <tsahara at iij>, who has analyzed the
 problem again, updated the patch, and carried out experiments for
 vulnerability scenarios. The confidential PR below is based on
 his work.

 PR security/58708


 To generate a diff of this commit:
 cvs rdiff -u -r1.440 -r1.441 src/sys/netinet/tcp_input.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->pending-pullups
State-Changed-By: rin@NetBSD.org
State-Changed-When: Tue, 08 Oct 2024 06:21:04 +0000
State-Changed-Why:
[pullup-10 #932], [pullup-9 #1894]


From: "Martin Husemann" <martin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/58708 CVS commit: [netbsd-10] src/sys/netinet
Date: Tue, 8 Oct 2024 11:24:50 +0000

 Module Name:	src
 Committed By:	martin
 Date:		Tue Oct  8 11:24:50 UTC 2024

 Modified Files:
 	src/sys/netinet [netbsd-10]: tcp_input.c

 Log Message:
 Pull up following revision(s) (requested by rin in ticket #932):

 	sys/netinet/tcp_input.c: revision 1.441

 tcp_reass: Mitigate CVE-2018-6922 (SegmentSmack)
 at a level of FreeBSD, by introducing an arbitrary (100) limit to
 the length of TCP reassembly queues:
 https://github.com/freebsd/freebsd-src/commit/95a914f6316874f5b0c45d491f2843dc810071ef

 Originally authored by ryo@.

 We thank Tomoyuki Sahara <tsahara at iij>, who has analyzed the
 problem again, updated the patch, and carried out experiments for
 vulnerability scenarios. The confidential PR below is based on
 his work.

 PR security/58708


 To generate a diff of this commit:
 cvs rdiff -u -r1.438 -r1.438.2.1 src/sys/netinet/tcp_input.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Martin Husemann" <martin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/58708 CVS commit: [netbsd-9] src/sys/netinet
Date: Tue, 8 Oct 2024 11:27:36 +0000

 Module Name:	src
 Committed By:	martin
 Date:		Tue Oct  8 11:27:36 UTC 2024

 Modified Files:
 	src/sys/netinet [netbsd-9]: tcp_input.c

 Log Message:
 Pull up following revision(s) (requested by rin in ticket #1894):

 	sys/netinet/tcp_input.c: revision 1.441

 tcp_reass: Mitigate CVE-2018-6922 (SegmentSmack)
 at a level of FreeBSD, by introducing an arbitrary (100) limit to
 the length of TCP reassembly queues:
 https://github.com/freebsd/freebsd-src/commit/95a914f6316874f5b0c45d491f2843dc810071ef

 Originally authored by ryo@.

 We thank Tomoyuki Sahara <tsahara at iij>, who has analyzed the
 problem again, updated the patch, and carried out experiments for
 vulnerability scenarios. The confidential PR below is based on
 his work.

 PR security/58708


 To generate a diff of this commit:
 cvs rdiff -u -r1.414.2.4 -r1.414.2.5 src/sys/netinet/tcp_input.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: pending-pullups->closed
State-Changed-By: riastradh@NetBSD.org
State-Changed-When: Wed, 09 Oct 2024 15:09:56 +0000
State-Changed-Why:
fixed in HEAD, pulled up to 9 and 10
pullup-10 #932 https://releng.netbsd.org/cgi-bin/req-10.cgi?show=932
pullup-9 #1894 https://releng.netbsd.org/cgi-bin/req-9.cgi?show=1894


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2024 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.