Received: by 2002:a5d:9c59:0:0:0:0:0 with SMTP id 25csp94372iof; Sun, 5 Jun 2022 22:10:48 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwDoSlaSEXmYF1UwNpXvASR8z5xKPUgM9f4b8B+GimmhaG+qXZIgPQ9lpo5alOod1vUbozy X-Received: by 2002:a17:902:7d8e:b0:162:22ff:495b with SMTP id a14-20020a1709027d8e00b0016222ff495bmr22509915plm.1.1654492248339; Sun, 05 Jun 2022 22:10:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1654492248; cv=none; d=google.com; s=arc-20160816; b=csedoZsG0+xoD7ME8RaIxzvAy2hn8dvfj6b6j2MHxeG201jKLMsL8tk5RequdumktI s4kp5nJREa5KaUWFo7Xe1Q+1rwb1wdG+vbPSuipGnPHt4q7z+Ihu+x4s9miY+yx0LoMf EKbuwSSOPM9iY25SJ7HdFyN103lH+FEC/YsGZ77ZJzo41+w0+DgfgUNz3+Z3GNckBWrp dcyLSvX2Yj6dGsOWg0chSCbmehFl4QJoZCQ4fpi/IpYTC5IsgVkLj0vyD1iBsvkTPVd4 7eUKtnwNU7DKzbLL3yhBVq0vq3N/Ra0EgXiCOcVomnpIAmH17LAvQuJsPV4psJn520VD m9pQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=uQNMFKW9urSqjPe8qzHbD5hcOAqYVq9SsWTCclMpSp8=; b=V1dOC5GXYeeoeiRGm/ufhP8t8pwO/gup5CdjVO96rnq/yam+lGaJPVi5yzGtfyOKZY nQAiMCJpr4kdLGwDE4ZVnPRSD62A0kyQkB07VA4kwOHD+V1lI+3CK2Rzqbczgys+o/vH 9tLNUe0b3d7VOfQG5/Lx/BGsuqIlCGBNLEmP5lOrNIyugavgoOry8/Qc77omYFqUj/3Z pOlQFqJG4cuQyNi+q/Qo7q2SbnLbqKlqwU4mI52Clv2yEkVAYilLFs53ZtKavHzGwjBV THFTRNL2txSUG8FxzdvxSD/EBSdtsa2yZ6ccB5fPmPc2IkQ7uML8VeKYfuYKyaHaNRJ9 uZww== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="fFub/l9k"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id e16-20020a637450000000b003fb04d0b55dsi20723596pgn.565.2022.06.05.22.10.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 05 Jun 2022 22:10:48 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="fFub/l9k"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 63E9813F92E; Sun, 5 Jun 2022 21:17:34 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345132AbiFCRsQ (ORCPT + 99 others); Fri, 3 Jun 2022 13:48:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46540 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345004AbiFCRsG (ORCPT ); Fri, 3 Jun 2022 13:48:06 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6E214579B6; Fri, 3 Jun 2022 10:44:36 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 1E6E0B823B0; Fri, 3 Jun 2022 17:44:35 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7E330C385B8; Fri, 3 Jun 2022 17:44:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1654278273; bh=311bfCw+p6Ifhva2ftAsh3+p6uETNMSRYcBZw1q//wg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fFub/l9kOly7JU40N9a5U467RcDA4S3lUj2p5+iMKKgEAnLj4+z54NaUhLnps38c0 QG82ZMw1mIn44nFym07SipsoeI0Qay1KvEGtvvXFSh+3ldFk4SO/8k4fue1iaL7vyW vQFUhfzktuXGcUm09KNkEiTr0HIyuFs3aH7Ea5Mk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Eric Dumazet , David Dworken , Willem de Bruijn , "David S. Miller" , Stefan Ghinea Subject: [PATCH 5.4 05/34] tcp: change source port randomizarion at connect() time Date: Fri, 3 Jun 2022 19:43:01 +0200 Message-Id: <20220603173816.151314434@linuxfoundation.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220603173815.990072516@linuxfoundation.org> References: <20220603173815.990072516@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eric Dumazet commit 190cc82489f46f9d88e73c81a47e14f80a791e1a upstream. RFC 6056 (Recommendations for Transport-Protocol Port Randomization) provides good summary of why source selection needs extra care. David Dworken reminded us that linux implements Algorithm 3 as described in RFC 6056 3.3.3 Quoting David : In the context of the web, this creates an interesting info leak where websites can count how many TCP connections a user's computer is establishing over time. For example, this allows a website to count exactly how many subresources a third party website loaded. This also allows: - Distinguishing between different users behind a VPN based on distinct source port ranges. - Tracking users over time across multiple networks. - Covert communication channels between different browsers/browser profiles running on the same computer - Tracking what applications are running on a computer based on the pattern of how fast source ports are getting incremented. Section 3.3.4 describes an enhancement, that reduces attackers ability to use the basic information currently stored into the shared 'u32 hint'. This change also decreases collision rate when multiple applications need to connect() to different destinations. Signed-off-by: Eric Dumazet Reported-by: David Dworken Cc: Willem de Bruijn Signed-off-by: David S. Miller Signed-off-by: Stefan Ghinea Signed-off-by: Greg Kroah-Hartman --- net/ipv4/inet_hashtables.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -671,6 +671,17 @@ unlock: } EXPORT_SYMBOL_GPL(inet_unhash); +/* RFC 6056 3.3.4. Algorithm 4: Double-Hash Port Selection Algorithm + * Note that we use 32bit integers (vs RFC 'short integers') + * because 2^16 is not a multiple of num_ephemeral and this + * property might be used by clever attacker. + * RFC claims using TABLE_LENGTH=10 buckets gives an improvement, + * we use 256 instead to really give more isolation and + * privacy, this only consumes 1 KB of kernel memory. + */ +#define INET_TABLE_PERTURB_SHIFT 8 +static u32 table_perturb[1 << INET_TABLE_PERTURB_SHIFT]; + int __inet_hash_connect(struct inet_timewait_death_row *death_row, struct sock *sk, u32 port_offset, int (*check_established)(struct inet_timewait_death_row *, @@ -684,8 +695,8 @@ int __inet_hash_connect(struct inet_time struct inet_bind_bucket *tb; u32 remaining, offset; int ret, i, low, high; - static u32 hint; int l3mdev; + u32 index; if (port) { head = &hinfo->bhash[inet_bhashfn(net, port, @@ -712,7 +723,10 @@ int __inet_hash_connect(struct inet_time if (likely(remaining > 1)) remaining &= ~1U; - offset = (hint + port_offset) % remaining; + net_get_random_once(table_perturb, sizeof(table_perturb)); + index = hash_32(port_offset, INET_TABLE_PERTURB_SHIFT); + + offset = (READ_ONCE(table_perturb[index]) + port_offset) % remaining; /* In first pass we try ports of @low parity. * inet_csk_get_port() does the opposite choice. */ @@ -766,7 +780,7 @@ next_port: return -EADDRNOTAVAIL; ok: - hint += i + 2; + WRITE_ONCE(table_perturb[index], READ_ONCE(table_perturb[index]) + i + 2); /* Head lock still held and bh's disabled */ inet_bind_hash(sk, tb, port);