From: John Hurley john.hurley@netronome.com
mainline inclusion from mainline-v5.3-rc1 commit 720f22fed81bc6fd1765db7014651b6718887bea category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I64END CVE: CVE-2022-4269
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h...
--------------------------------
The TC_ACT_REINSERT return type was added as an in-kernel only option to allow a packet ingress or egress redirect. This is used to avoid unnecessary skb clones in situations where they are not required. If a TC hook returns this code then the packet is 'reinserted' and no skb consume is carried out as no clone took place.
This return type is only used in act_mirred. Rather than have the reinsert called from the main datapath, call it directly in act_mirred. Instead of returning TC_ACT_REINSERT, change the type to the new TC_ACT_CONSUMED which tells the caller that the packet has been stolen by another process and that no consume call is required.
Moving all redirect calls to the act_mirred code is in preparation for tracking recursion created by act_mirred.
Signed-off-by: John Hurley john.hurley@netronome.com Reviewed-by: Simon Horman simon.horman@netronome.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Ziyang Xuan william.xuanziyang@huawei.com Reviewed-by: Liu Jian liujian56@huawei.com Reviewed-by: Wang Weiyang wangweiyang2@huawei.com Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com --- include/net/pkt_cls.h | 2 +- include/net/sch_generic.h | 2 +- net/core/dev.c | 4 +--- net/sched/act_mirred.c | 3 ++- 4 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index 75a3f3fdb359..5d381f2af64b 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -8,7 +8,7 @@ #include <net/act_api.h>
/* TC action not accessible from user space */ -#define TC_ACT_REINSERT (TC_ACT_VALUE_MAX + 1) +#define TC_ACT_CONSUMED (TC_ACT_VALUE_MAX + 1)
/* Basic packet classifier frontend definitions. */
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index f5f45390828d..101481ad5270 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -258,7 +258,7 @@ struct tcf_result { }; const struct tcf_proto *goto_tp;
- /* used by the TC_ACT_REINSERT action */ + /* used in the skb_tc_reinsert function */ struct { bool ingress; struct gnet_stats_queue *qstats; diff --git a/net/core/dev.c b/net/core/dev.c index 09b5b73ecdd8..f1af4712a78b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4662,9 +4662,7 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret, __skb_push(skb, skb->mac_len); skb_do_redirect(skb); return NULL; - case TC_ACT_REINSERT: - /* this does not scrub the packet, and updates stats on error */ - skb_tc_reinsert(skb, &cl_res); + case TC_ACT_CONSUMED: return NULL; default: break; diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 9ee7c7f479fc..55683fc96ad3 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -269,7 +269,8 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, if (use_reinsert) { res->ingress = want_ingress; res->qstats = this_cpu_ptr(m->common.cpu_qstats); - return TC_ACT_REINSERT; + skb_tc_reinsert(skb, res); + return TC_ACT_CONSUMED; } }