summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorM A Ramdhan <ramdhan@starlabs.sg>2023-07-05 12:15:30 -0400
committerLee Jones <joneslee@google.com>2023-09-18 08:33:40 +0100
commit11518ebf9bcc5beef148d8016900a407ea88dbda (patch)
tree577f570ae30b6fe0227db30a1800e0750a3affb1
parenta1d365a9a023a50006bdda48d1658158efeac623 (diff)
downloadcommon-android12-5.10-2023-02.tar.gz
UPSTREAM: net/sched: cls_fw: Fix improper refcount update leads to use-after-freeandroid12-5.10-2023-02_r11deprecated/android12-5.10-2023-02android12-5.10-2023-02
[ Upstream commit 0323bce598eea038714f941ce2b22541c46d488f ] In the event of a failure in tcf_change_indev(), fw_set_parms() will immediately return an error after incrementing or decrementing reference counter in tcf_bind_filter(). If attacker can control reference counter to zero and make reference freed, leading to use after free. In order to prevent this, move the point of possible failure above the point where the TC_FW_CLASSID is handled. Bug: 292252062 Bug: 290783303 Bug: 297799749 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: M A Ramdhan <ramdhan@starlabs.sg> Signed-off-by: M A Ramdhan <ramdhan@starlabs.sg> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Reviewed-by: Pedro Tammela <pctammela@mojatatu.com> Message-ID: <20230705161530.52003-1-ramdhan@starlabs.sg> Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org> (cherry picked from commit c91fb29bb07ee4dd40aabd1e41f19c0f92ac3199) Signed-off-by: Lee Jones <joneslee@google.com> (cherry picked from commit a4fd973abf2b043734a0b001b9b47ff2a0f63c59) Signed-off-by: Pindar Yang <pindaryang@google.com> Change-Id: I9bf6f540b4eb23ea5641fb3efe6f3e621d7b6151
-rw-r--r--net/sched/cls_fw.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index ec945294626a..41f0898a5a56 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -210,11 +210,6 @@ static int fw_set_parms(struct net *net, struct tcf_proto *tp,
if (err < 0)
return err;
- if (tb[TCA_FW_CLASSID]) {
- f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]);
- tcf_bind_filter(tp, &f->res, base);
- }
-
if (tb[TCA_FW_INDEV]) {
int ret;
ret = tcf_change_indev(net, tb[TCA_FW_INDEV], extack);
@@ -231,6 +226,11 @@ static int fw_set_parms(struct net *net, struct tcf_proto *tp,
} else if (head->mask != 0xFFFFFFFF)
return err;
+ if (tb[TCA_FW_CLASSID]) {
+ f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]);
+ tcf_bind_filter(tp, &f->res, base);
+ }
+
return 0;
}