summaryrefslogtreecommitdiffstats
path: root/iptables
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2020-05-04 19:30:29 +0200
committerPhil Sutter <phil@nwl.cc>2020-05-11 14:28:29 +0200
commit5fdb447fdfe877bd6236830b4a2507d4d61bc1a1 (patch)
treea8d83c947d620c99e3a3abb97361d501371167f4 /iptables
parent196401937d76f990ad59a4a93cd5a45e91a2b12a (diff)
nft: Fix leaks in ebt_add_policy_rule()
The function leaked memory allocated in temporary struct iptables_command_state, clean it immediately after use. In any of the udata-related error cases, allocated nftnl_rule would leak, fix this by introducing a common error path to goto. In regular code path, the allocated nftnl_rule would still leak: batch_obj_del() does not free rules in NFT_COMPAT_RULE_APPEND jobs, as they typically sit in cache as well. Policy rules in turn weren't added to cache: They are created immediately before commit and never referenced from other rules. Add them now so they are freed just like regular rules. Fixes: aff1162b3e4b7 ("ebtables-nft: Support user-defined chain policies") Signed-off-by: Phil Sutter <phil@nwl.cc>
Diffstat (limited to 'iptables')
-rw-r--r--iptables/nft.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/iptables/nft.c b/iptables/nft.c
index addde1b5..c0b5e2fc 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -2970,27 +2970,33 @@ static int ebt_add_policy_rule(struct nftnl_chain *c, void *data)
r = nft_rule_new(h, nftnl_chain_get_str(c, NFTNL_CHAIN_NAME),
nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE), &cs);
+ ebt_cs_clean(&cs);
+
if (!r)
return -1;
udata = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
if (!udata)
- return -1;
+ goto err_free_rule;
if (!nftnl_udata_put_u32(udata, UDATA_TYPE_EBTABLES_POLICY, 1))
- return -1;
+ goto err_free_rule;
nftnl_rule_set_data(r, NFTNL_RULE_USERDATA,
nftnl_udata_buf_data(udata),
nftnl_udata_buf_len(udata));
nftnl_udata_buf_free(udata);
- if (!batch_rule_add(h, NFT_COMPAT_RULE_APPEND, r)) {
- nftnl_rule_free(r);
- return -1;
- }
+ if (!batch_rule_add(h, NFT_COMPAT_RULE_APPEND, r))
+ goto err_free_rule;
+
+ /* add the rule to chain so it is freed later */
+ nftnl_chain_rule_add_tail(r, c);
return 0;
+err_free_rule:
+ nftnl_rule_free(r);
+ return -1;
}
int ebt_set_user_chain_policy(struct nft_handle *h, const char *table,