Received: by 2002:a6b:500f:0:0:0:0:0 with SMTP id e15csp3629770iob; Tue, 17 May 2022 04:20:38 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy09cxt3JkZ1OU3BC3LF/YVjqrtrTiQCkdW82/uM2n1BxUkZR5kq0N9xXXd43q6fGiQljcC X-Received: by 2002:a62:e117:0:b0:510:c651:229a with SMTP id q23-20020a62e117000000b00510c651229amr22150102pfh.67.1652786437661; Tue, 17 May 2022 04:20:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1652786437; cv=none; d=google.com; s=arc-20160816; b=MckrIheWKho4aCOkDlgK+HUM5UaApUUzTRTjSy0OUjwNfv9vv0ukBC83MvcoSHlXnQ dkoan0+hKpuvSjaa/Xo67c+8O3FKkkMtbrMKpljn7w1pjIGFMdIyMJrtT+lT3kL7CIbv iwDqlRS9OPfPc5PKzqmYiEurw/3D0ww83U2YdX7vYqDCnhy243MWD0zbSaAZvf6n7NgB lOXV0TdWW80MDGek8KNLCMEx8WexZI6BKbOyGOjn6aLao8OTb0IRJV1ida+qPLP5aMR4 WqnsdlD4VW/F5sYqLT8oNkTQqTVbSVlh7em4K71eQdmGCiLomvIGJGiLH7otUqr6b/1T eY4w== 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=H7Gqa9uQ4ByHPUMf9YqLwF8LGyqtM5oipXrwXvFMGQE=; b=FOE+Ta+6ntBwTuRR6a1HB5vtyonKLzmQKaQs6FtdbYuzLVkioaHeegXiVmXrpc0Bl8 1yPufebSuwIzslMOXodDsiLIFFjfYa1Y2i4utu5t+BE/bePDMNNQXE+WOMzc9w1TZsaX SWDyrp3gdn0ArSSOVYrHHBzy2UyFZ0AfHkZSh0K+qqmYGl8Axv/D0OvDBJkalCLg0c/V eG3RHacy5FMFnoHYeig4OhYAxMZGpqmR5TMeqUrhsr27h0mVrXOlXM2gRZ2CEM9QD4p1 1vA2UXxOELhqoGtbgPtIRQLlyFWFdIoHrccgRC4FlEBHrM+YoW6W8c7HOobUAa4aPGq3 Xo3Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=YyAIm4DQ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id nu13-20020a17090b1b0d00b001d97ad1c408si3004757pjb.147.2022.05.17.04.20.23; Tue, 17 May 2022 04:20:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=YyAIm4DQ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 S1347228AbiEPU3Z (ORCPT + 99 others); Mon, 16 May 2022 16:29:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57626 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350358AbiEPUBI (ORCPT ); Mon, 16 May 2022 16:01:08 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 895F849FA1; Mon, 16 May 2022 12:55:18 -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 dfw.source.kernel.org (Postfix) with ESMTPS id 6D36660EC4; Mon, 16 May 2022 19:54:59 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 791B6C385AA; Mon, 16 May 2022 19:54:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1652730898; bh=BmEpJ/ld1VzVukNx4iIl4AsXqK1rY8EOvE6U4VYro2A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YyAIm4DQtmWzHAGjvoFlne2cWU2MPNhm9XqDC5/+pmXej7Am2qF3P2maSgxgznKgR /o6H+CFPlouk7uHEei/z/M+bQGMJIMimW32SO0C8jXDG+Ec36J0MhzKf8gT0wRQCOV 3VnTbRQkMAxdkSG/Otx2HwzUAQP2GAwtYGwboy48= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Mat Martineau , Geliang Tang , Paolo Abeni , Jamal Hadi Salim , Jakub Kicinski , Sasha Levin Subject: [PATCH 5.17 038/114] net/sched: act_pedit: really ensure the skb is writable Date: Mon, 16 May 2022 21:36:12 +0200 Message-Id: <20220516193626.583897601@linuxfoundation.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220516193625.489108457@linuxfoundation.org> References: <20220516193625.489108457@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=-7.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham 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: Paolo Abeni [ Upstream commit 8b796475fd7882663a870456466a4fb315cc1bd6 ] Currently pedit tries to ensure that the accessed skb offset is writable via skb_unclone(). The action potentially allows touching any skb bytes, so it may end-up modifying shared data. The above causes some sporadic MPTCP self-test failures, due to this code: tc -n $ns2 filter add dev ns2eth$i egress \ protocol ip prio 1000 \ handle 42 fw \ action pedit munge offset 148 u8 invert \ pipe csum tcp \ index 100 The above modifies a data byte outside the skb head and the skb is a cloned one, carrying a TCP output packet. This change addresses the issue by keeping track of a rough over-estimate highest skb offset accessed by the action and ensuring such offset is really writable. Note that this may cause performance regressions in some scenarios, but hopefully pedit is not in the critical path. Fixes: db2c24175d14 ("act_pedit: access skb->data safely") Acked-by: Mat Martineau Tested-by: Geliang Tang Signed-off-by: Paolo Abeni Acked-by: Jamal Hadi Salim Link: https://lore.kernel.org/r/1fcf78e6679d0a287dd61bb0f04730ce33b3255d.1652194627.git.pabeni@redhat.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- include/net/tc_act/tc_pedit.h | 1 + net/sched/act_pedit.c | 26 ++++++++++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/include/net/tc_act/tc_pedit.h b/include/net/tc_act/tc_pedit.h index 748cf87a4d7e..3e02709a1df6 100644 --- a/include/net/tc_act/tc_pedit.h +++ b/include/net/tc_act/tc_pedit.h @@ -14,6 +14,7 @@ struct tcf_pedit { struct tc_action common; unsigned char tcfp_nkeys; unsigned char tcfp_flags; + u32 tcfp_off_max_hint; struct tc_pedit_key *tcfp_keys; struct tcf_pedit_key_ex *tcfp_keys_ex; }; diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 31fcd279c177..0eaaf1f45de1 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -149,7 +149,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, struct nlattr *pattr; struct tcf_pedit *p; int ret = 0, err; - int ksize; + int i, ksize; u32 index; if (!nla) { @@ -228,6 +228,18 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, p->tcfp_nkeys = parm->nkeys; } memcpy(p->tcfp_keys, parm->keys, ksize); + p->tcfp_off_max_hint = 0; + for (i = 0; i < p->tcfp_nkeys; ++i) { + u32 cur = p->tcfp_keys[i].off; + + /* The AT option can read a single byte, we can bound the actual + * value with uchar max. + */ + cur += (0xff & p->tcfp_keys[i].offmask) >> p->tcfp_keys[i].shift; + + /* Each key touches 4 bytes starting from the computed offset */ + p->tcfp_off_max_hint = max(p->tcfp_off_max_hint, cur + 4); + } p->tcfp_flags = parm->flags; goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); @@ -308,13 +320,18 @@ static int tcf_pedit_act(struct sk_buff *skb, const struct tc_action *a, struct tcf_result *res) { struct tcf_pedit *p = to_pedit(a); + u32 max_offset; int i; - if (skb_unclone(skb, GFP_ATOMIC)) - return p->tcf_action; - spin_lock(&p->tcf_lock); + max_offset = (skb_transport_header_was_set(skb) ? + skb_transport_offset(skb) : + skb_network_offset(skb)) + + p->tcfp_off_max_hint; + if (skb_ensure_writable(skb, min(skb->len, max_offset))) + goto unlock; + tcf_lastuse_update(&p->tcf_tm); if (p->tcfp_nkeys > 0) { @@ -403,6 +420,7 @@ static int tcf_pedit_act(struct sk_buff *skb, const struct tc_action *a, p->tcf_qstats.overlimits++; done: bstats_update(&p->tcf_bstats, skb); +unlock: spin_unlock(&p->tcf_lock); return p->tcf_action; } -- 2.35.1