Received: by 2002:a6b:500f:0:0:0:0:0 with SMTP id e15csp3275543iob; Mon, 16 May 2022 17:53:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzIfaGykfA747tfrWvY3u2dA7F+m3ZiJUOkWLvWBa9XGpY8AtE6rlge3l7MBgcgI/yYUZr8 X-Received: by 2002:a05:6a00:843:b0:510:7550:6005 with SMTP id q3-20020a056a00084300b0051075506005mr20010274pfk.75.1652748810930; Mon, 16 May 2022 17:53:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1652748810; cv=none; d=google.com; s=arc-20160816; b=bByuSbmqpnxojGanVlCrsd2vNQ+tkw7/9Eed6Njg4KUzJHTE6cvVOcGJPejHisoys5 wzqSnb3MIDiKCfpY8lZny6az3aBG5Hk7GQ6TLgogr4OQ7adoi3upjARa033LqC6/Rrfr 33DZ+ZVMLGaWrVFGKLsnVtFCCKA6/2w1Ps1oSWMcp9/t/sgK89OGrCj9rBm62YpytTRn N4J2wTaSs9PIGHAn8RGerAtc/xStFZESH/S53y8sD4Vwc7uirC42ei+nV/lNuzbQO/BX 7tEs6ftpvrDRBhaKsBUJX1zYX0QtGYBdxv+ZXlHi6xBPDhOM5j8X1C7kVTQ79FTw9cML jjRQ== 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=CVqsxZ/V7tjB7+miiDaNSKswCBYSJ4Wj3yZvslyV89o=; b=sCoegG/cSRq76+COKqsYiVM/ywxj5PKf/V0i4bhq1xRZfIgUFw8Ao6facyvlmuQo3B bKAkU1QGXTEhUtDLf0MFq5Xm84p8b2SU/jv4R4u6uyzdlhb8XV84be3cBFxHUnX4ZGrL r7M2rkamEaXQH0v8uLrqtYIet+DF4GaAB7YyHax5SirnivWYzb6bxR9S7hQ3Of6Rn3Db ew7U3pHalB4fszmDcDL16O0RkH9SKheOBJJmVWzT+j650+U6PgSuauG9qDCp8FPMQo44 rhMj9Szk/N/P4f09Y+CpJq9kMhwCqmvPTO4mfUuUpB4BYNEqIPgeZDrjYF5sXs+fzHgI avHA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=KgVM1Upv; 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 lx9-20020a17090b4b0900b001decaeaf1easi1142541pjb.6.2022.05.16.17.53.20; Mon, 16 May 2022 17:53:30 -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=KgVM1Upv; 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 S231293AbiEPUJo (ORCPT + 99 others); Mon, 16 May 2022 16:09:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41096 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346832AbiEPT4C (ORCPT ); Mon, 16 May 2022 15:56:02 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B7B447568; Mon, 16 May 2022 12:49:16 -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 45265B81611; Mon, 16 May 2022 19:49:14 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 72767C385AA; Mon, 16 May 2022 19:49:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1652730553; bh=cqLfwRyUYFur1S7Q1GFZ4P6pcd1QS7jbOKJu4tqaOig=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KgVM1UpvtfPw1+XUj70LT02AVOPA3JhFRbfEn9zTda9zNRoNMyLiPjbLKFjKAdkCQ XLdKuBVBy5WfwS7gVoerZw53P6dhauoHycV97+TyOaUu4O6TOisknceYm40WUBYlFA cxfKP/ClMRdzRNJI7hqvJc8S7THWz6QK3oGUtTjU= 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.15 035/102] net/sched: act_pedit: really ensure the skb is writable Date: Mon, 16 May 2022 21:36:09 +0200 Message-Id: <20220516193625.008379502@linuxfoundation.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220516193623.989270214@linuxfoundation.org> References: <20220516193623.989270214@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 c6c862c459cc..cfadd613644a 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