From: Greg Kroah-Hartman Date: Fri, 4 Aug 2023 10:02:05 +0000 (+0200) Subject: 4.14-stable patches X-Git-Tag: v4.14.321~80 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0a1ef3473f6953a31252ff3a3cedd36f6f661406;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: net-sched-cls_u32-fix-reference-counter-leak-leading-to-overflow.patch --- diff --git a/queue-4.14/net-sched-cls_u32-fix-reference-counter-leak-leading-to-overflow.patch b/queue-4.14/net-sched-cls_u32-fix-reference-counter-leak-leading-to-overflow.patch new file mode 100644 index 00000000000..9562c1b431d --- /dev/null +++ b/queue-4.14/net-sched-cls_u32-fix-reference-counter-leak-leading-to-overflow.patch @@ -0,0 +1,77 @@ +From 04c55383fa5689357bcdd2c8036725a55ed632bc Mon Sep 17 00:00:00 2001 +From: Lee Jones +Date: Thu, 8 Jun 2023 08:29:03 +0100 +Subject: net/sched: cls_u32: Fix reference counter leak leading to overflow + +From: Lee Jones + +commit 04c55383fa5689357bcdd2c8036725a55ed632bc upstream. + +In the event of a failure in tcf_change_indev(), u32_set_parms() will +immediately return without decrementing the recently incremented +reference counter. If this happens enough times, the counter will +rollover and the reference freed, leading to a double free which can be +used to do 'bad things'. + +In order to prevent this, move the point of possible failure above the +point where the reference counter is incremented. Also save any +meaningful return values to be applied to the return data at the +appropriate point in time. + +This issue was caught with KASAN. + +Fixes: 705c7091262d ("net: sched: cls_u32: no need to call tcf_exts_change for newly allocated struct") +Suggested-by: Eric Dumazet +Signed-off-by: Lee Jones +Reviewed-by: Eric Dumazet +Acked-by: Jamal Hadi Salim +Signed-off-by: David S. Miller +Signed-off-by: Rishabh Bhatnagar +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/cls_u32.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +--- a/net/sched/cls_u32.c ++++ b/net/sched/cls_u32.c +@@ -774,11 +774,22 @@ static int u32_set_parms(struct net *net + struct nlattr *est, bool ovr) + { + int err; ++#ifdef CONFIG_NET_CLS_IND ++ int ifindex = -1; ++#endif + + err = tcf_exts_validate(net, tp, tb, est, &n->exts, ovr); + if (err < 0) + return err; + ++#ifdef CONFIG_NET_CLS_IND ++ if (tb[TCA_U32_INDEV]) { ++ ifindex = tcf_change_indev(net, tb[TCA_U32_INDEV]); ++ if (ifindex < 0) ++ return -EINVAL; ++ } ++#endif ++ + if (tb[TCA_U32_LINK]) { + u32 handle = nla_get_u32(tb[TCA_U32_LINK]); + struct tc_u_hnode *ht_down = NULL, *ht_old; +@@ -806,14 +817,10 @@ static int u32_set_parms(struct net *net + } + + #ifdef CONFIG_NET_CLS_IND +- if (tb[TCA_U32_INDEV]) { +- int ret; +- ret = tcf_change_indev(net, tb[TCA_U32_INDEV]); +- if (ret < 0) +- return -EINVAL; +- n->ifindex = ret; +- } ++ if (ifindex >= 0) ++ n->ifindex = ifindex; + #endif ++ + return 0; + } + diff --git a/queue-4.14/series b/queue-4.14/series index a1e0816dbcb..c235f3cdd85 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -177,3 +177,4 @@ dm-cache-policy-smq-ensure-io-doesn-t-prevent-cleaner-policy-progress.patch drm-client-fix-memory-leak-in-drm_client_target_cloned.patch net-sched-cls_fw-fix-improper-refcount-update-leads-to-use-after-free.patch net-sched-sch_qfq-account-for-stab-overhead-in-qfq_enqueue.patch +net-sched-cls_u32-fix-reference-counter-leak-leading-to-overflow.patch