Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp66350pxb; Mon, 13 Sep 2021 13:06:20 -0700 (PDT) X-Google-Smtp-Source: ABdhPJypQZRFkwOXSl2vqj1iBgmD0co9PXB9FiqJjRYSTengs8hSOVEl0ZCn37O/m56UOHiFOs0C X-Received: by 2002:a17:906:16d4:: with SMTP id t20mr3121040ejd.482.1631563580629; Mon, 13 Sep 2021 13:06:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631563580; cv=none; d=google.com; s=arc-20160816; b=Sn5soB3MZgeXHSB3w1C4ujROLfYfeQtY9syyBfG/VaEv5RzrM37TKc18O02Gp3Mld5 lkYkYKnBx4E0QpW61jNmEG26si4jD5kgoN/RyqMGQrLg+5ZoyuBEq8n+/zNNfPLSWBaC bHZYgmplbsqPUWexNkUQmzRtrU8aL7wOTpcgO5wOgdi2yJ2HJJHi6v3PvjnXSuC/Z3YD 0u5KkgYrt+hY5XUO5UIuvKBzDoy8yll7zPjjiouG6R1e1AA/Lke1At4PuvGRqNenr8qC AUJT04BKwQ+1t7jzOUSWLPeWR8Xk2RUhRxUYo+mUzl4mDJV/kM9Cpi4yEIyyrg1ZGC+2 fopQ== 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=969dtsTeiuIePVSRF3h85VjG/fh3voVJQ6bKXdksYqI=; b=cZV0B68YIysN9lkiMv/5LPZyKpy8BgVQO16cTfANTQq5u5sXM+89vVZnce8QrLoxkz UBaoOvaSwsgzaNL/Z/a9kM2DVgYzbhP1/ECVePFq9qihM11Mq7CHpC1XOxvPD0Tjin9V Oa7LL9W/Ai3n10iNSTErr1+hEU578UIwE3P3wwcXINI2DaYNsxI2CLLhHiXEKRhmU+1T tlWog8B4znYOXkgS4NUcwK7+6iXyj/2WzbvbC/vGW6i7v3ONccQth+xkTpgJ0axn/p3T nC7LiCTRnpxePO0YaLdKq/7uf9pTew7JG+05f6qzsIK9Hb5Q6O54CxnOnPHEFuKAJouZ 60aQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=XMtkcAla; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.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 vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id kl24si9167533ejc.190.2021.09.13.13.05.46; Mon, 13 Sep 2021 13:06:20 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=XMtkcAla; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.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: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243541AbhIMNo1 (ORCPT + 99 others); Mon, 13 Sep 2021 09:44:27 -0400 Received: from mail.kernel.org ([198.145.29.99]:35706 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241164AbhIMNi7 (ORCPT ); Mon, 13 Sep 2021 09:38:59 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 361C2610E7; Mon, 13 Sep 2021 13:28:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1631539723; bh=CQ4BpHNEpcu1ROYvXKdWueVQ1Kr7eHxYG1j07hyti0s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XMtkcAlaXkzhlaxlXMAFXQEyNbXVOOz+Cif9SCAnit16CB1TSZlTyiuEHd7Ra6zjn VhmENlM0SbJjkPc1ui0szJ6s4AHXRCXqh+imA6P7HVE8AxEXL4wL9LGM12Xubeu2JA NKF1vHrJRmgnT8mgY1tZjX67POfC8m4x6Os7R1dY= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Martin KaFai Lau , Andrii Nakryiko , Eric Dumazet , Kuniyuki Iwashima , Yonghong Song , Sasha Levin Subject: [PATCH 5.10 103/236] tcp: seq_file: Avoid skipping sk during tcp_seek_last_pos Date: Mon, 13 Sep 2021 15:13:28 +0200 Message-Id: <20210913131103.847706651@linuxfoundation.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210913131100.316353015@linuxfoundation.org> References: <20210913131100.316353015@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Martin KaFai Lau [ Upstream commit 525e2f9fd0229eb10cb460a9e6d978257f24804e ] st->bucket stores the current bucket number. st->offset stores the offset within this bucket that is the sk to be seq_show(). Thus, st->offset only makes sense within the same st->bucket. These two variables are an optimization for the common no-lseek case. When resuming the seq_file iteration (i.e. seq_start()), tcp_seek_last_pos() tries to continue from the st->offset at bucket st->bucket. However, it is possible that the bucket pointed by st->bucket has changed and st->offset may end up skipping the whole st->bucket without finding a sk. In this case, tcp_seek_last_pos() currently continues to satisfy the offset condition in the next (and incorrect) bucket. Instead, regardless of the offset value, the first sk of the next bucket should be returned. Thus, "bucket == st->bucket" check is added to tcp_seek_last_pos(). The chance of hitting this is small and the issue is a decade old, so targeting for the next tree. Fixes: a8b690f98baf ("tcp: Fix slowness in read /proc/net/tcp") Signed-off-by: Martin KaFai Lau Signed-off-by: Andrii Nakryiko Reviewed-by: Eric Dumazet Acked-by: Kuniyuki Iwashima Acked-by: Yonghong Song Link: https://lore.kernel.org/bpf/20210701200541.1033917-1-kafai@fb.com Signed-off-by: Sasha Levin --- net/ipv4/tcp_ipv4.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 04e259a04443..71395e745bc5 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2417,6 +2417,7 @@ static void *tcp_get_idx(struct seq_file *seq, loff_t pos) static void *tcp_seek_last_pos(struct seq_file *seq) { struct tcp_iter_state *st = seq->private; + int bucket = st->bucket; int offset = st->offset; int orig_num = st->num; void *rc = NULL; @@ -2427,7 +2428,7 @@ static void *tcp_seek_last_pos(struct seq_file *seq) break; st->state = TCP_SEQ_STATE_LISTENING; rc = listening_get_next(seq, NULL); - while (offset-- && rc) + while (offset-- && rc && bucket == st->bucket) rc = listening_get_next(seq, rc); if (rc) break; @@ -2438,7 +2439,7 @@ static void *tcp_seek_last_pos(struct seq_file *seq) if (st->bucket > tcp_hashinfo.ehash_mask) break; rc = established_get_first(seq); - while (offset-- && rc) + while (offset-- && rc && bucket == st->bucket) rc = established_get_next(seq, rc); } -- 2.30.2