Received: by 2002:a6b:500f:0:0:0:0:0 with SMTP id e15csp3317941iob; Mon, 16 May 2022 19:12:41 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz++OXjK9yInUerDtanLll9oGFFHCN+6ziN9hYtoovcJIGGp0jc0Vuu1AuhQUHMr1Kzmvxw X-Received: by 2002:a65:4581:0:b0:3f2:638f:6f76 with SMTP id o1-20020a654581000000b003f2638f6f76mr8018712pgq.324.1652753561246; Mon, 16 May 2022 19:12:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1652753561; cv=none; d=google.com; s=arc-20160816; b=MdVWqkIwfpSrErAl2UUIdVLefsKQgWC+TQjUAdjhUfR4obuljp+NjUWS/pfwtOZ8Es /w8Q37pn06pqaDd6PnWAVDVZe0PYdr4J0BSGSjPYxkCCjaWnkAZzc6GGzq2OkpCdU/X6 n44udcat4SZoJrszE76dIJhECymN1lqYQ1ltiLni+etozkFTK2SND5EgWzAY4y55TEf0 yGgU1KpCH4n07SFNhPsxz9zYwJZrI81vQoviIT3+4NPh3VVHTBuh1MjoWvtyQ6Dhm+bc Nw9gqmhhh36GSg+dfKMnOAE8/ncDgliIWtaMWPEY5rGUK0fS9h60qu0B9p+0lVrWErK7 G5gw== 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=k8LZ4bA2Kzy1mgchWS4uDaQWm+7LclOGfFXbZIM7nhs=; b=kwesA4NxncJc+jnf2HMmk3CMoviJRAbZmzw0LdqyYDE28H8+vu6gYCJ0uCra5C2sWp 0/403OskwhotVfqWbrZhfW7xfKH2lBbEgTWJ2hrxTaeE2uXohQXd6k3FF67JEZd2axj9 iNVdgCcjHMcJbWXBqUg8zxrjtN2r88ANDlTRJk8dE2FqmrPnW9NHWtsJ6Sb+p8EWA3ER pl+pL7FlhHVmUvD6XKcwevL/i0qnWORfPjvggEEq5hm4OXOm3idnGPv3iMN2Rr/dZH+g oWFbtbT4Zq0+LVZJjvv9wJ5XoBnhDk7lG7yb7rpaCAAprFI2V3sVBq/BGVJFYRQ847y0 Saiw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=eGTy5YmR; 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 m1-20020a170902f64100b00153b2d16510si14105176plg.280.2022.05.16.19.12.28; Mon, 16 May 2022 19:12:41 -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=eGTy5YmR; 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 S1345995AbiEPTsn (ORCPT + 99 others); Mon, 16 May 2022 15:48:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42660 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346376AbiEPTmE (ORCPT ); Mon, 16 May 2022 15:42:04 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 39AF818B; Mon, 16 May 2022 12:40:39 -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 7220B61538; Mon, 16 May 2022 19:40:38 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7AF0FC385AA; Mon, 16 May 2022 19:40:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1652730037; bh=QCo496fYDmwgMawnPL1ftwATDrYep+6x7Q72Vwn/ptE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eGTy5YmRtDhj681AOVg3EyxO1pDOmmbHnBlG0gi6fQ08zLsB6riOBIRBoOukdvBaW sdaCEA0d+lDm2/i01X6FK7ACCH/D1Ds5/Dz2TxzKdeT+UmRX1vlGfNVID14Ekw7yD4 qp9DrbuI3w6ndk4LQi6iduA23Kz5IXlvBsYWD5X8= 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 4.19 11/32] net/sched: act_pedit: really ensure the skb is writable Date: Mon, 16 May 2022 21:36:25 +0200 Message-Id: <20220516193615.111458274@linuxfoundation.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220516193614.773450018@linuxfoundation.org> References: <20220516193614.773450018@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 fac3ad4a86de..bd74e94527a2 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 ce14fafb36a1..fec0f7fdb015 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -148,7 +148,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) { @@ -221,6 +221,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; p->tcf_action = parm->action; @@ -298,13 +310,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) { @@ -393,6 +410,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