* [PATCH 0/7] Netfilter/IPVS fixes for net
@ 2015-03-05 20:48 Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 1/7] netfilter: nft_compat: don't truncate ethernet protocol type to u8 Pablo Neira Ayuso
` (7 more replies)
0 siblings, 8 replies; 9+ messages in thread
From: Pablo Neira Ayuso @ 2015-03-05 20:48 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
Hi David,
The following patchset contains Netfilter/IPVS fixes for your net tree,
they are:
1) Don't truncate ethernet protocol type to u8 in nft_compat, from
Arturo Borrero.
2) Fix several problems in the addition/deletion of elements in nf_tables.
3) Fix module refcount leak in ip_vs_sync, from Julian Anastasov.
4) Fix a race condition in the abort path in the nf_tables transaction
infrastructure. Basically aborted rules can show up as active rules
until changes are unrolled, oneliner from Patrick McHardy.
5) Check for overflows in the data area of the rule, also from Patrick.
6) Fix off-by-one in the per-rule user data size field. This introduces
a new nft_userdata structure that is placed at the beginning of the
user data area that contains the length to save some bits from the
rule and we only need one bit to indicate its presence, from Patrick.
7) Fix rule replacement error path, the replaced rule is deleted on
error instead of leaving it in place. This has been fixed by relying
on the abort path to undo the incomplete replacement.
You can pull these changes from:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git
Thanks a lot!
----------------------------------------------------------------
The following changes since commit 3f34b24a732bab9635c4b32823268c37c01b40f0:
af_packet: allow packets defragmentation not only for hash fanout type (2015-02-21 23:00:18 -0500)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git master
for you to fetch changes up to 59900e0a019e7c2bdb7809a03ed5742d311b15b3:
netfilter: nf_tables: fix error handling of rule replacement (2015-03-04 18:46:08 +0100)
----------------------------------------------------------------
Arturo Borrero (1):
netfilter: nft_compat: don't truncate ethernet protocol type to u8
Julian Anastasov (1):
ipvs: add missing ip_vs_pe_put in sync code
Pablo Neira Ayuso (3):
netfilter: nf_tables: fix addition/deletion of elements from commit/abort
Merge https://git.kernel.org/.../horms/ipvs
netfilter: nf_tables: fix error handling of rule replacement
Patrick McHardy (3):
netfilter: nf_tables: fix transaction race condition
netfilter: nf_tables: check for overflow of rule dlen field
netfilter: nf_tables: fix userdata length overflow
include/net/netfilter/nf_tables.h | 22 +++++++++++--
net/netfilter/ipvs/ip_vs_sync.c | 3 ++
net/netfilter/nf_tables_api.c | 61 ++++++++++++++++++++++---------------
net/netfilter/nft_compat.c | 14 ++++-----
4 files changed, 65 insertions(+), 35 deletions(-)
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/7] netfilter: nft_compat: don't truncate ethernet protocol type to u8
2015-03-05 20:48 [PATCH 0/7] Netfilter/IPVS fixes for net Pablo Neira Ayuso
@ 2015-03-05 20:48 ` Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 2/7] netfilter: nf_tables: fix addition/deletion of elements from commit/abort Pablo Neira Ayuso
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Pablo Neira Ayuso @ 2015-03-05 20:48 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Arturo Borrero <arturo.borrero.glez@gmail.com>
Use u16 for protocol and then cast it to __be16
>> net/netfilter/nft_compat.c:140:37: sparse: incorrect type in assignment (different base types)
net/netfilter/nft_compat.c:140:37: expected restricted __be16 [usertype] ethproto
net/netfilter/nft_compat.c:140:37: got unsigned char [unsigned] [usertype] proto
>> net/netfilter/nft_compat.c:351:37: sparse: incorrect type in assignment (different base types)
net/netfilter/nft_compat.c:351:37: expected restricted __be16 [usertype] ethproto
net/netfilter/nft_compat.c:351:37: got unsigned char [unsigned] [usertype] proto
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_compat.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 1279cd8..213584c 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -123,7 +123,7 @@ static void
nft_target_set_tgchk_param(struct xt_tgchk_param *par,
const struct nft_ctx *ctx,
struct xt_target *target, void *info,
- union nft_entry *entry, u8 proto, bool inv)
+ union nft_entry *entry, u16 proto, bool inv)
{
par->net = ctx->net;
par->table = ctx->table->name;
@@ -137,7 +137,7 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par,
entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0;
break;
case NFPROTO_BRIDGE:
- entry->ebt.ethproto = proto;
+ entry->ebt.ethproto = (__force __be16)proto;
entry->ebt.invflags = inv ? EBT_IPROTO : 0;
break;
}
@@ -171,7 +171,7 @@ static const struct nla_policy nft_rule_compat_policy[NFTA_RULE_COMPAT_MAX + 1]
[NFTA_RULE_COMPAT_FLAGS] = { .type = NLA_U32 },
};
-static int nft_parse_compat(const struct nlattr *attr, u8 *proto, bool *inv)
+static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv)
{
struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1];
u32 flags;
@@ -203,7 +203,7 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
struct xt_target *target = expr->ops->data;
struct xt_tgchk_param par;
size_t size = XT_ALIGN(nla_len(tb[NFTA_TARGET_INFO]));
- u8 proto = 0;
+ u16 proto = 0;
bool inv = false;
union nft_entry e = {};
int ret;
@@ -334,7 +334,7 @@ static const struct nla_policy nft_match_policy[NFTA_MATCH_MAX + 1] = {
static void
nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
struct xt_match *match, void *info,
- union nft_entry *entry, u8 proto, bool inv)
+ union nft_entry *entry, u16 proto, bool inv)
{
par->net = ctx->net;
par->table = ctx->table->name;
@@ -348,7 +348,7 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0;
break;
case NFPROTO_BRIDGE:
- entry->ebt.ethproto = proto;
+ entry->ebt.ethproto = (__force __be16)proto;
entry->ebt.invflags = inv ? EBT_IPROTO : 0;
break;
}
@@ -385,7 +385,7 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
struct xt_match *match = expr->ops->data;
struct xt_mtchk_param par;
size_t size = XT_ALIGN(nla_len(tb[NFTA_MATCH_INFO]));
- u8 proto = 0;
+ u16 proto = 0;
bool inv = false;
union nft_entry e = {};
int ret;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/7] netfilter: nf_tables: fix addition/deletion of elements from commit/abort
2015-03-05 20:48 [PATCH 0/7] Netfilter/IPVS fixes for net Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 1/7] netfilter: nft_compat: don't truncate ethernet protocol type to u8 Pablo Neira Ayuso
@ 2015-03-05 20:48 ` Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 3/7] ipvs: add missing ip_vs_pe_put in sync code Pablo Neira Ayuso
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Pablo Neira Ayuso @ 2015-03-05 20:48 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
We have several problems in this path:
1) There is a use-after-free when removing individual elements from
the commit path.
2) We have to uninit() the data part of the element from the abort
path to avoid a chain refcount leak.
3) We have to check for set->flags to see if there's a mapping, instead
of the element flags.
4) We have to check for !(flags & NFT_SET_ELEM_INTERVAL_END) to skip
elements that are part of the interval that have no data part, so
they don't need to be uninit().
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 199fd0f..a8c9462 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -3612,12 +3612,11 @@ static int nf_tables_commit(struct sk_buff *skb)
&te->elem,
NFT_MSG_DELSETELEM, 0);
te->set->ops->get(te->set, &te->elem);
- te->set->ops->remove(te->set, &te->elem);
nft_data_uninit(&te->elem.key, NFT_DATA_VALUE);
- if (te->elem.flags & NFT_SET_MAP) {
- nft_data_uninit(&te->elem.data,
- te->set->dtype);
- }
+ if (te->set->flags & NFT_SET_MAP &&
+ !(te->elem.flags & NFT_SET_ELEM_INTERVAL_END))
+ nft_data_uninit(&te->elem.data, te->set->dtype);
+ te->set->ops->remove(te->set, &te->elem);
nft_trans_destroy(trans);
break;
}
@@ -3658,7 +3657,7 @@ static int nf_tables_abort(struct sk_buff *skb)
{
struct net *net = sock_net(skb->sk);
struct nft_trans *trans, *next;
- struct nft_set *set;
+ struct nft_trans_elem *te;
list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
switch (trans->msg_type) {
@@ -3719,9 +3718,13 @@ static int nf_tables_abort(struct sk_buff *skb)
break;
case NFT_MSG_NEWSETELEM:
nft_trans_elem_set(trans)->nelems--;
- set = nft_trans_elem_set(trans);
- set->ops->get(set, &nft_trans_elem(trans));
- set->ops->remove(set, &nft_trans_elem(trans));
+ te = (struct nft_trans_elem *)trans->data;
+ te->set->ops->get(te->set, &te->elem);
+ nft_data_uninit(&te->elem.key, NFT_DATA_VALUE);
+ if (te->set->flags & NFT_SET_MAP &&
+ !(te->elem.flags & NFT_SET_ELEM_INTERVAL_END))
+ nft_data_uninit(&te->elem.data, te->set->dtype);
+ te->set->ops->remove(te->set, &te->elem);
nft_trans_destroy(trans);
break;
case NFT_MSG_DELSETELEM:
--
1.7.10.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/7] ipvs: add missing ip_vs_pe_put in sync code
2015-03-05 20:48 [PATCH 0/7] Netfilter/IPVS fixes for net Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 1/7] netfilter: nft_compat: don't truncate ethernet protocol type to u8 Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 2/7] netfilter: nf_tables: fix addition/deletion of elements from commit/abort Pablo Neira Ayuso
@ 2015-03-05 20:48 ` Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 4/7] netfilter: nf_tables: fix transaction race condition Pablo Neira Ayuso
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Pablo Neira Ayuso @ 2015-03-05 20:48 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Julian Anastasov <ja@ssi.bg>
ip_vs_conn_fill_param_sync() gets in param.pe a module
reference for persistence engine from __ip_vs_pe_getbyname()
but forgets to put it. Problem occurs in backup for
sync protocol v1 (2.6.39).
Also, pe_data usually comes in sync messages for
connection templates and ip_vs_conn_new() copies
the pointer only in this case. Make sure pe_data
is not leaked if it comes unexpectedly for normal
connections. Leak can happen only if bogus messages
are sent to backup server.
Fixes: fe5e7a1efb66 ("IPVS: Backup, Adding Version 1 receive capability")
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
net/netfilter/ipvs/ip_vs_sync.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index c47ffd7..d93ceeb 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -896,6 +896,8 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
IP_VS_DBG(2, "BACKUP, add new conn. failed\n");
return;
}
+ if (!(flags & IP_VS_CONN_F_TEMPLATE))
+ kfree(param->pe_data);
}
if (opt)
@@ -1169,6 +1171,7 @@ static inline int ip_vs_proc_sync_conn(struct net *net, __u8 *p, __u8 *msg_end)
(opt_flags & IPVS_OPT_F_SEQ_DATA ? &opt : NULL)
);
#endif
+ ip_vs_pe_put(param.pe);
return 0;
/* Error exit */
out:
--
1.7.10.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/7] netfilter: nf_tables: fix transaction race condition
2015-03-05 20:48 [PATCH 0/7] Netfilter/IPVS fixes for net Pablo Neira Ayuso
` (2 preceding siblings ...)
2015-03-05 20:48 ` [PATCH 3/7] ipvs: add missing ip_vs_pe_put in sync code Pablo Neira Ayuso
@ 2015-03-05 20:48 ` Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 5/7] netfilter: nf_tables: check for overflow of rule dlen field Pablo Neira Ayuso
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Pablo Neira Ayuso @ 2015-03-05 20:48 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
A race condition exists in the rule transaction code for rules that
get added and removed within the same transaction.
The new rule starts out as inactive in the current and active in the
next generation and is inserted into the ruleset. When it is deleted,
it is additionally set to inactive in the next generation as well.
On commit the next generation is begun, then the actions are finalized.
For the new rule this would mean clearing out the inactive bit for
the previously current, now next generation.
However nft_rule_clear() clears out the bits for *both* generations,
activating the rule in the current generation, where it should be
deactivated due to being deleted. The rule will thus be active until
the deletion is finalized, removing the rule from the ruleset.
Similarly, when aborting a transaction for the same case, the undo
of insertion will remove it from the RCU protected rule list, the
deletion will clear out all bits. However until the next RCU
synchronization after all operations have been undone, the rule is
active on CPUs which can still see the rule on the list.
Generally, there may never be any modifications of the current
generations' inactive bit since this defeats the entire purpose of
atomicity. Change nft_rule_clear() to only touch the next generations
bit to fix this.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index a8c9462..6fb532b 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -227,7 +227,7 @@ nft_rule_deactivate_next(struct net *net, struct nft_rule *rule)
static inline void nft_rule_clear(struct net *net, struct nft_rule *rule)
{
- rule->genmask = 0;
+ rule->genmask &= ~(1 << gencursor_next(net));
}
static int
--
1.7.10.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/7] netfilter: nf_tables: check for overflow of rule dlen field
2015-03-05 20:48 [PATCH 0/7] Netfilter/IPVS fixes for net Pablo Neira Ayuso
` (3 preceding siblings ...)
2015-03-05 20:48 ` [PATCH 4/7] netfilter: nf_tables: fix transaction race condition Pablo Neira Ayuso
@ 2015-03-05 20:48 ` Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 6/7] netfilter: nf_tables: fix userdata length overflow Pablo Neira Ayuso
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Pablo Neira Ayuso @ 2015-03-05 20:48 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Check that the space required for the expressions doesn't exceed the
size of the dlen field, which would lead to the iterators crashing.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 6fb532b..7baafd5 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1968,6 +1968,10 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
n++;
}
}
+ /* Check for overflow of dlen field */
+ err = -EFBIG;
+ if (size >= 1 << 12)
+ goto err1;
if (nla[NFTA_RULE_USERDATA])
ulen = nla_len(nla[NFTA_RULE_USERDATA]);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 6/7] netfilter: nf_tables: fix userdata length overflow
2015-03-05 20:48 [PATCH 0/7] Netfilter/IPVS fixes for net Pablo Neira Ayuso
` (4 preceding siblings ...)
2015-03-05 20:48 ` [PATCH 5/7] netfilter: nf_tables: check for overflow of rule dlen field Pablo Neira Ayuso
@ 2015-03-05 20:48 ` Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 7/7] netfilter: nf_tables: fix error handling of rule replacement Pablo Neira Ayuso
2015-03-06 2:51 ` [PATCH 0/7] Netfilter/IPVS fixes for net David Miller
7 siblings, 0 replies; 9+ messages in thread
From: Pablo Neira Ayuso @ 2015-03-05 20:48 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
The NFT_USERDATA_MAXLEN is defined to 256, however we only have a u8
to store its size. Introduce a struct nft_userdata which contains a
length field and indicate its presence using a single bit in the rule.
The length field of struct nft_userdata is also a u8, however we don't
store zero sized data, so the actual length is udata->len + 1.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 22 +++++++++++++++++++---
net/netfilter/nf_tables_api.c | 28 +++++++++++++++++++---------
2 files changed, 38 insertions(+), 12 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 9eaaa78..decb9a0 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -119,6 +119,22 @@ int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
const struct nft_data *data,
enum nft_data_types type);
+
+/**
+ * struct nft_userdata - user defined data associated with an object
+ *
+ * @len: length of the data
+ * @data: content
+ *
+ * The presence of user data is indicated in an object specific fashion,
+ * so a length of zero can't occur and the value "len" indicates data
+ * of length len + 1.
+ */
+struct nft_userdata {
+ u8 len;
+ unsigned char data[0];
+};
+
/**
* struct nft_set_elem - generic representation of set elements
*
@@ -380,7 +396,7 @@ static inline void *nft_expr_priv(const struct nft_expr *expr)
* @handle: rule handle
* @genmask: generation mask
* @dlen: length of expression data
- * @ulen: length of user data (used for comments)
+ * @udata: user data is appended to the rule
* @data: expression data
*/
struct nft_rule {
@@ -388,7 +404,7 @@ struct nft_rule {
u64 handle:42,
genmask:2,
dlen:12,
- ulen:8;
+ udata:1;
unsigned char data[]
__attribute__((aligned(__alignof__(struct nft_expr))));
};
@@ -476,7 +492,7 @@ static inline struct nft_expr *nft_expr_last(const struct nft_rule *rule)
return (struct nft_expr *)&rule->data[rule->dlen];
}
-static inline void *nft_userdata(const struct nft_rule *rule)
+static inline struct nft_userdata *nft_userdata(const struct nft_rule *rule)
{
return (void *)&rule->data[rule->dlen];
}
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 7baafd5..74e4b87 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1711,9 +1711,12 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
}
nla_nest_end(skb, list);
- if (rule->ulen &&
- nla_put(skb, NFTA_RULE_USERDATA, rule->ulen, nft_userdata(rule)))
- goto nla_put_failure;
+ if (rule->udata) {
+ struct nft_userdata *udata = nft_userdata(rule);
+ if (nla_put(skb, NFTA_RULE_USERDATA, udata->len + 1,
+ udata->data) < 0)
+ goto nla_put_failure;
+ }
nlmsg_end(skb, nlh);
return 0;
@@ -1896,11 +1899,12 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
struct nft_table *table;
struct nft_chain *chain;
struct nft_rule *rule, *old_rule = NULL;
+ struct nft_userdata *udata;
struct nft_trans *trans = NULL;
struct nft_expr *expr;
struct nft_ctx ctx;
struct nlattr *tmp;
- unsigned int size, i, n, ulen = 0;
+ unsigned int size, i, n, ulen = 0, usize = 0;
int err, rem;
bool create;
u64 handle, pos_handle;
@@ -1973,11 +1977,14 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
if (size >= 1 << 12)
goto err1;
- if (nla[NFTA_RULE_USERDATA])
+ if (nla[NFTA_RULE_USERDATA]) {
ulen = nla_len(nla[NFTA_RULE_USERDATA]);
+ if (ulen > 0)
+ usize = sizeof(struct nft_userdata) + ulen;
+ }
err = -ENOMEM;
- rule = kzalloc(sizeof(*rule) + size + ulen, GFP_KERNEL);
+ rule = kzalloc(sizeof(*rule) + size + usize, GFP_KERNEL);
if (rule == NULL)
goto err1;
@@ -1985,10 +1992,13 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
rule->handle = handle;
rule->dlen = size;
- rule->ulen = ulen;
+ rule->udata = ulen ? 1 : 0;
- if (ulen)
- nla_memcpy(nft_userdata(rule), nla[NFTA_RULE_USERDATA], ulen);
+ if (ulen) {
+ udata = nft_userdata(rule);
+ udata->len = ulen - 1;
+ nla_memcpy(udata->data, nla[NFTA_RULE_USERDATA], ulen);
+ }
expr = nft_expr_first(rule);
for (i = 0; i < n; i++) {
--
1.7.10.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 7/7] netfilter: nf_tables: fix error handling of rule replacement
2015-03-05 20:48 [PATCH 0/7] Netfilter/IPVS fixes for net Pablo Neira Ayuso
` (5 preceding siblings ...)
2015-03-05 20:48 ` [PATCH 6/7] netfilter: nf_tables: fix userdata length overflow Pablo Neira Ayuso
@ 2015-03-05 20:48 ` Pablo Neira Ayuso
2015-03-06 2:51 ` [PATCH 0/7] Netfilter/IPVS fixes for net David Miller
7 siblings, 0 replies; 9+ messages in thread
From: Pablo Neira Ayuso @ 2015-03-05 20:48 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In general, if a transaction object is added to the list successfully,
we can rely on the abort path to undo what we've done. This allows us to
simplify the error handling of the rule replacement path in
nf_tables_newrule().
This implicitly fixes an unnecessary removal of the old rule, which
needs to be left in place if we fail to replace.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 74e4b87..6ab7779 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2045,12 +2045,6 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
err3:
list_del_rcu(&rule->list);
- if (trans) {
- list_del_rcu(&nft_trans_rule(trans)->list);
- nft_rule_clear(net, nft_trans_rule(trans));
- nft_trans_destroy(trans);
- chain->use++;
- }
err2:
nf_tables_rule_destroy(&ctx, rule);
err1:
--
1.7.10.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 0/7] Netfilter/IPVS fixes for net
2015-03-05 20:48 [PATCH 0/7] Netfilter/IPVS fixes for net Pablo Neira Ayuso
` (6 preceding siblings ...)
2015-03-05 20:48 ` [PATCH 7/7] netfilter: nf_tables: fix error handling of rule replacement Pablo Neira Ayuso
@ 2015-03-06 2:51 ` David Miller
7 siblings, 0 replies; 9+ messages in thread
From: David Miller @ 2015-03-06 2:51 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, netdev
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Thu, 5 Mar 2015 21:48:42 +0100
> The following patchset contains Netfilter/IPVS fixes for your net tree,
> they are:
...
Pulled, thanks a lot Pablo.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2015-03-06 2:51 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-05 20:48 [PATCH 0/7] Netfilter/IPVS fixes for net Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 1/7] netfilter: nft_compat: don't truncate ethernet protocol type to u8 Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 2/7] netfilter: nf_tables: fix addition/deletion of elements from commit/abort Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 3/7] ipvs: add missing ip_vs_pe_put in sync code Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 4/7] netfilter: nf_tables: fix transaction race condition Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 5/7] netfilter: nf_tables: check for overflow of rule dlen field Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 6/7] netfilter: nf_tables: fix userdata length overflow Pablo Neira Ayuso
2015-03-05 20:48 ` [PATCH 7/7] netfilter: nf_tables: fix error handling of rule replacement Pablo Neira Ayuso
2015-03-06 2:51 ` [PATCH 0/7] Netfilter/IPVS fixes for net David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).