From nobody Wed Jun 26 04:50:23 2024 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4W88QR3SBXz5NyxG; Wed, 26 Jun 2024 04:50:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4W88QR1Vg5z56yh; Wed, 26 Jun 2024 04:50:23 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1719377423; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=BEujx95rcDhAwozidVX3UxPLKqxxOPNvFk/34uNo8l8=; b=FZvgi2a2GTWaxjArIoDzqm3LFmKW+4I5DOMB7uUuKKZQJ4gsdBswCZRrHfgWuobLCZox0C +5QtABDkVRJc8PTWgTCf3kL0rw32sRO53+rdlIIuga4k/Bw3MVejntNa4s/73Mbt6AIW30 sgxIeXjoNuZhRyeoTzLabwj/4LcKvT974xMkzN104su8nYn6fkSZZLhWH7n7UeUUBsEse4 hPk6bEQ95foDcELh5i5dDlxLRhnjs8PhjzaiIAeIcOo/YfwjHH/Jd0DkkN1e6nIxe1tgyS ab122FMERBp0rBICmwx9N+UUDbZHOiEgO44I/O01UjZTIgTb/a5qJtkyg1XzdQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1719377423; a=rsa-sha256; cv=none; b=e0wFEesPJHSJCAo7+Tb3HNxs3FS2gjKr92h9xWWX9WGj1smNNCHg8eKTcTSTYqlZFX1Pyp z2k0xGPgDaOSaRDBF0Tx+QP2t5x/Z7Zp9/iUSWF9k53TAcCrM1AdMn8e/T4YR1F6yxc/tt jeoi1LppfgTfuM997saF0raB6n6TxEGhN01CH20mP3VxybieLNN0570Eee0b7UFNjXVPA1 Lqvc/pXX5T26X6KxMioVW+weULXVAkqJzug7/s4PwlLjozDbRReNTS6twF499afKZr/SJm 5JUxQVCHU1HsaOD68vbtf9CN307tu1WqkrDfqwktyIyUiAK7IejhpMvsqQUOlw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1719377423; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=BEujx95rcDhAwozidVX3UxPLKqxxOPNvFk/34uNo8l8=; b=qMCGMpFzypEsX7LioN8xpTxx0nD8oi9+t0jaahjP/wdpkKn/3UvkjEBXppymx8GB0K4dmA IU6E+uZW1FPmh6Fqfqb8lxhWyl0/PvH+W5pKmxzTf3ajGb2QMpOw0fto0veyMsXbxg9rYE hhaTTPP9qu5icI5XRTc4myNN/6ZPy/299izvYQ+b1WgDBPuo61TwnGnE2Edd7cvzRzaKnT wi230Qb+WdSY9uWMlkqvWKtn/T38lRq/mHV3WmnP7563DE48MgUEbRx/kpcNXN5lQc/E6m K2Vvda2FMofSs795Ibk58wEsun2s5MjH9zYbBdT2fbmSRS7Mux3NwXxjwUR1Tw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4W88QR14pZzXBw; Wed, 26 Jun 2024 04:50:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 45Q4oN8R063718; Wed, 26 Jun 2024 04:50:23 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 45Q4oNKF063715; Wed, 26 Jun 2024 04:50:23 GMT (envelope-from git) Date: Wed, 26 Jun 2024 04:50:23 GMT Message-Id: <202406260450.45Q4oNKF063715@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Zhenlei Huang Subject: git: d8acc7277cec - stable/14 - icmp: improve ICMP limit jitter List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: zlei X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: d8acc7277cecde08092289a58caceeca1b455888 Auto-Submitted: auto-generated The branch stable/14 has been updated by zlei: URL: https://cgit.FreeBSD.org/src/commit/?id=d8acc7277cecde08092289a58caceeca1b455888 commit d8acc7277cecde08092289a58caceeca1b455888 Author: Gleb Smirnoff AuthorDate: 2024-03-24 16:13:23 +0000 Commit: Zhenlei Huang CommitDate: 2024-06-26 04:48:43 +0000 icmp: improve ICMP limit jitter Instead of fixing up invalid values set by a user in badport_bandlim() which is a fast path function, provide a sysctl handler sysctl_icmplim_and_jitter(), that will check that jitter is less than the limit. Provide jitter initilization function icmplim_new_jitter() used at boot, in the sysctl handler and when we actually hit the limit. This also fixes no jitter on a fresh booted system until first limit hit. Instead of CVE number provide link the the actual paper that explains what and why we are doing here. The CVE number isn't very informative, it will just tell you what RedHat version you need to upgrade to. Reviewed by: kp, tuexen, zlei Differential Revision: https://reviews.freebsd.org/D44478 (cherry picked from commit ac44739fd834f51cacb26485a4140fd482e20150) --- sys/netinet/ip_icmp.c | 81 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 22 deletions(-) diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index 83034f9d9dd4..dcf387aa3c1c 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -82,19 +82,22 @@ extern ipproto_ctlinput_t *ip_ctlprotox[]; * routines to turnaround packets back to the originator, and * host table maintenance routines. */ -VNET_DEFINE_STATIC(int, icmplim) = 200; +static int sysctl_icmplim_and_jitter(SYSCTL_HANDLER_ARGS); +VNET_DEFINE_STATIC(u_int, icmplim) = 200; #define V_icmplim VNET(icmplim) -SYSCTL_INT(_net_inet_icmp, ICMPCTL_ICMPLIM, icmplim, CTLFLAG_VNET | CTLFLAG_RW, - &VNET_NAME(icmplim), 0, - "Maximum number of ICMP responses per second"); +SYSCTL_PROC(_net_inet_icmp, ICMPCTL_ICMPLIM, icmplim, CTLTYPE_UINT | + CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(icmplim), 0, + &sysctl_icmplim_and_jitter, "IU", + "Maximum number of ICMP responses per second"); VNET_DEFINE_STATIC(int, icmplim_curr_jitter) = 0; #define V_icmplim_curr_jitter VNET(icmplim_curr_jitter) -VNET_DEFINE_STATIC(int, icmplim_jitter) = 16; +VNET_DEFINE_STATIC(u_int, icmplim_jitter) = 16; #define V_icmplim_jitter VNET(icmplim_jitter) -SYSCTL_INT(_net_inet_icmp, OID_AUTO, icmplim_jitter, CTLFLAG_VNET | CTLFLAG_RW, - &VNET_NAME(icmplim_jitter), 0, - "Random icmplim jitter adjustment limit"); +SYSCTL_PROC(_net_inet_icmp, OID_AUTO, icmplim_jitter, CTLTYPE_UINT | + CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(icmplim_jitter), 0, + &sysctl_icmplim_and_jitter, "IU", + "Random icmplim jitter adjustment limit"); VNET_DEFINE_STATIC(int, icmplim_output) = 1; #define V_icmplim_output VNET(icmplim_output) @@ -1106,6 +1109,52 @@ static const char *icmp_rate_descrs[BANDLIM_MAX] = { [BANDLIM_SCTP_OOTB] = "sctp ootb", }; +static void +icmplim_new_jitter(void) +{ + /* + * Adjust limit +/- to jitter the measurement to deny a side-channel + * port scan as in https://dl.acm.org/doi/10.1145/3372297.3417280 + */ + if (V_icmplim_jitter > 0) + V_icmplim_curr_jitter = + arc4random_uniform(V_icmplim_jitter * 2 + 1) - + V_icmplim_jitter; +} + +static int +sysctl_icmplim_and_jitter(SYSCTL_HANDLER_ARGS) +{ + uint32_t new; + int error; + bool lim; + + MPASS(oidp->oid_arg1 == &VNET_NAME(icmplim) || + oidp->oid_arg1 == &VNET_NAME(icmplim_jitter)); + + lim = (oidp->oid_arg1 == &VNET_NAME(icmplim)); + new = lim ? V_icmplim : V_icmplim_jitter; + error = sysctl_handle_int(oidp, &new, 0, req); + if (error == 0 && req->newptr) { + if (lim) { + if (new <= V_icmplim_jitter) + error = EINVAL; + else + V_icmplim = new; + } else { + if (new >= V_icmplim) + error = EINVAL; + else { + V_icmplim_jitter = new; + icmplim_new_jitter(); + } + } + } + MPASS(V_icmplim + V_icmplim_curr_jitter > 0); + + return (error); +} + static void icmp_bandlimit_init(void) { @@ -1114,6 +1163,7 @@ icmp_bandlimit_init(void) V_icmp_rates[i].cr_rate = counter_u64_alloc(M_WAITOK); V_icmp_rates[i].cr_ticks = ticks; } + icmplim_new_jitter(); } VNET_SYSINIT(icmp_bandlimit, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, icmp_bandlimit_init, NULL); @@ -1141,9 +1191,6 @@ badport_bandlim(int which) KASSERT(which >= 0 && which < BANDLIM_MAX, ("%s: which %d", __func__, which)); - if ((V_icmplim + V_icmplim_curr_jitter) <= 0) - V_icmplim_curr_jitter = -V_icmplim + 1; - pps = counter_ratecheck(&V_icmp_rates[which], V_icmplim + V_icmplim_curr_jitter); if (pps > 0) { @@ -1152,17 +1199,7 @@ badport_bandlim(int which) "Limiting %s response from %jd to %d packets/sec\n", icmp_rate_descrs[which], (intmax_t )pps, V_icmplim + V_icmplim_curr_jitter); - /* - * Adjust limit +/- to jitter the measurement to deny a - * side-channel port scan as in CVE-2020-25705 - */ - if (V_icmplim_jitter > 0) { - int32_t inc = - arc4random_uniform(V_icmplim_jitter * 2 +1) - - V_icmplim_jitter; - - V_icmplim_curr_jitter = inc; - } + icmplim_new_jitter(); } if (pps == -1) return (-1);