diff options
author | Ilya Pronin <ipronin@twitter.com> | 2018-08-23 23:12:25 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2018-10-10 09:48:55 (GMT) |
commit | 1ac40683a879a602dbf8c42372677fb94f958a7d (patch) | |
tree | 7872233e2e0a50c57f9605602805f12d5a96008b | |
parent | d1b5f55b312bc296ef25ce2a4a7520e74db2daca (diff) | |
download | libnl-1ac40683a879a602dbf8c42372677fb94f958a7d.zip libnl-1ac40683a879a602dbf8c42372677fb94f958a7d.tar.gz libnl-1ac40683a879a602dbf8c42372677fb94f958a7d.tar.bz2 |
route/cls: fix potential memory leak
rtnl_act_append() cannot add more than TCA_ACT_MAX_PRIO actions to the
same list. Because of that rtnl_basic_add_action() and
rtnl_u32_add_action() should not increment the reference counter of the
given action until it is successfully added to the filter's list.
Signed-off-by: Ilya Pronin <ipronin@twitter.com>
Fixes: e5d9b828f6ec64fd77854578fbf1c33f214f3ac4
https://github.com/thom311/libnl/pull/201
-rw-r--r-- | lib/route/cls/basic.c | 6 | ||||
-rw-r--r-- | lib/route/cls/u32.c | 6 |
2 files changed, 10 insertions, 2 deletions
diff --git a/lib/route/cls/basic.c b/lib/route/cls/basic.c index 912ded6..3581c60 100644 --- a/lib/route/cls/basic.c +++ b/lib/route/cls/basic.c @@ -220,6 +220,7 @@ struct rtnl_ematch_tree *rtnl_basic_get_ematch(struct rtnl_cls *cls) int rtnl_basic_add_action(struct rtnl_cls *cls, struct rtnl_act *act) { struct rtnl_basic *b; + int err; if (!act) return 0; @@ -228,9 +229,12 @@ int rtnl_basic_add_action(struct rtnl_cls *cls, struct rtnl_act *act) return -NLE_NOMEM; b->b_mask |= BASIC_ATTR_ACTION; + if ((err = rtnl_act_append(&b->b_act, act))) + return err; + /* In case user frees it */ rtnl_act_get(act); - return rtnl_act_append(&b->b_act, act); + return 0; } struct rtnl_act* rtnl_basic_get_action(struct rtnl_cls *cls) diff --git a/lib/route/cls/u32.c b/lib/route/cls/u32.c index 0078888..f06bc24 100644 --- a/lib/route/cls/u32.c +++ b/lib/route/cls/u32.c @@ -526,6 +526,7 @@ int rtnl_u32_set_cls_terminal(struct rtnl_cls *cls) int rtnl_u32_add_action(struct rtnl_cls *cls, struct rtnl_act *act) { struct rtnl_u32 *u; + int err; if (!act) return 0; @@ -534,9 +535,12 @@ int rtnl_u32_add_action(struct rtnl_cls *cls, struct rtnl_act *act) return -NLE_NOMEM; u->cu_mask |= U32_ATTR_ACTION; + if ((err = rtnl_act_append(&u->cu_act, act))) + return err; + /* In case user frees it */ rtnl_act_get(act); - return rtnl_act_append(&u->cu_act, act); + return 0; } struct rtnl_act* rtnl_u32_get_action(struct rtnl_cls *cls) |