Skip to content

Commit 281f65d

Browse files
Jinjie Ruandavem330
authored andcommitted
net: microchip: vcap api: Fix possible memory leak for vcap_dup_rule()
Inject fault When select CONFIG_VCAP_KUNIT_TEST, the below memory leak occurs. If kzalloc() for duprule succeeds, but the following kmemdup() fails, the duprule, ckf and caf memory will be leaked. So kfree them in the error path. unreferenced object 0xffff122744c50600 (size 192): comm "kunit_try_catch", pid 346, jiffies 4294896122 (age 911.812s) hex dump (first 32 bytes): 10 27 00 00 04 00 00 00 1e 00 00 00 2c 01 00 00 .'..........,... 00 00 00 00 00 00 00 00 18 06 c5 44 27 12 ff ff ...........D'... backtrace: [<00000000394b0db8>] __kmem_cache_alloc_node+0x274/0x2f8 [<0000000001bedc67>] kmalloc_trace+0x38/0x88 [<00000000b0612f98>] vcap_dup_rule+0x50/0x460 [<000000005d2d3aca>] vcap_add_rule+0x8cc/0x1038 [<00000000eef9d0f8>] test_vcap_xn_rule_creator.constprop.0.isra.0+0x238/0x494 [<00000000cbda607b>] vcap_api_rule_remove_in_front_test+0x1ac/0x698 [<00000000c8766299>] kunit_try_run_case+0xe0/0x20c [<00000000c4fe9186>] kunit_generic_run_threadfn_adapter+0x50/0x94 [<00000000f6864acf>] kthread+0x2e8/0x374 [<0000000022e639b3>] ret_from_fork+0x10/0x20 Fixes: 814e769 ("net: microchip: vcap api: Add a storage state to a VCAP rule") Signed-off-by: Jinjie Ruan <[email protected]> Reviewed-by: Simon Horman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent e73d1ab commit 281f65d

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

drivers/net/ethernet/microchip/vcap/vcap_api.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,18 +1021,32 @@ static struct vcap_rule_internal *vcap_dup_rule(struct vcap_rule_internal *ri,
10211021
list_for_each_entry(ckf, &ri->data.keyfields, ctrl.list) {
10221022
newckf = kmemdup(ckf, sizeof(*newckf), GFP_KERNEL);
10231023
if (!newckf)
1024-
return ERR_PTR(-ENOMEM);
1024+
goto err;
10251025
list_add_tail(&newckf->ctrl.list, &duprule->data.keyfields);
10261026
}
10271027

10281028
list_for_each_entry(caf, &ri->data.actionfields, ctrl.list) {
10291029
newcaf = kmemdup(caf, sizeof(*newcaf), GFP_KERNEL);
10301030
if (!newcaf)
1031-
return ERR_PTR(-ENOMEM);
1031+
goto err;
10321032
list_add_tail(&newcaf->ctrl.list, &duprule->data.actionfields);
10331033
}
10341034

10351035
return duprule;
1036+
1037+
err:
1038+
list_for_each_entry_safe(ckf, newckf, &duprule->data.keyfields, ctrl.list) {
1039+
list_del(&ckf->ctrl.list);
1040+
kfree(ckf);
1041+
}
1042+
1043+
list_for_each_entry_safe(caf, newcaf, &duprule->data.actionfields, ctrl.list) {
1044+
list_del(&caf->ctrl.list);
1045+
kfree(caf);
1046+
}
1047+
1048+
kfree(duprule);
1049+
return ERR_PTR(-ENOMEM);
10361050
}
10371051

10381052
static void vcap_apply_width(u8 *dst, int width, int bytes)

0 commit comments

Comments
 (0)