Skip to content

Commit a8f33c0

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains Netfilter fixes for net: 1) Missing sanitization of rateest userspace string, bug has been triggered by syzbot, patch from Florian Westphal. 2) Report EOPNOTSUPP on missing set features in nft_dynset, otherwise error reporting to userspace via EINVAL is misleading since this is reserved for malformed netlink requests. 3) New binaries with old kernels might silently accept several set element expressions. New binaries set on the NFT_SET_EXPR and NFT_DYNSET_F_EXPR flags to request for several expressions per element, hence old kernels which do not support for this bail out with EOPNOTSUPP. * git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf: netfilter: nftables: add set expression flags netfilter: nft_dynset: report EOPNOTSUPP on missing set feature netfilter: xt_RATEEST: reject non-null terminated string from userspace ==================== Link: https://lore.kernel.org/r/20210103192920.18639-1-pablo@netfilter.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 08ad483 + b4e70d8 commit a8f33c0

4 files changed

Lines changed: 21 additions & 6 deletions

File tree

include/uapi/linux/netfilter/nf_tables.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ enum nft_rule_compat_attributes {
293293
* @NFT_SET_EVAL: set can be updated from the evaluation path
294294
* @NFT_SET_OBJECT: set contains stateful objects
295295
* @NFT_SET_CONCAT: set contains a concatenation
296+
* @NFT_SET_EXPR: set contains expressions
296297
*/
297298
enum nft_set_flags {
298299
NFT_SET_ANONYMOUS = 0x1,
@@ -303,6 +304,7 @@ enum nft_set_flags {
303304
NFT_SET_EVAL = 0x20,
304305
NFT_SET_OBJECT = 0x40,
305306
NFT_SET_CONCAT = 0x80,
307+
NFT_SET_EXPR = 0x100,
306308
};
307309

308310
/**
@@ -706,6 +708,7 @@ enum nft_dynset_ops {
706708

707709
enum nft_dynset_flags {
708710
NFT_DYNSET_F_INV = (1 << 0),
711+
NFT_DYNSET_F_EXPR = (1 << 1),
709712
};
710713

711714
/**

net/netfilter/nf_tables_api.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4162,7 +4162,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
41624162
if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
41634163
NFT_SET_INTERVAL | NFT_SET_TIMEOUT |
41644164
NFT_SET_MAP | NFT_SET_EVAL |
4165-
NFT_SET_OBJECT | NFT_SET_CONCAT))
4165+
NFT_SET_OBJECT | NFT_SET_CONCAT | NFT_SET_EXPR))
41664166
return -EOPNOTSUPP;
41674167
/* Only one of these operations is supported */
41684168
if ((flags & (NFT_SET_MAP | NFT_SET_OBJECT)) ==
@@ -4304,6 +4304,10 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
43044304
struct nlattr *tmp;
43054305
int left;
43064306

4307+
if (!(flags & NFT_SET_EXPR)) {
4308+
err = -EINVAL;
4309+
goto err_set_alloc_name;
4310+
}
43074311
i = 0;
43084312
nla_for_each_nested(tmp, nla[NFTA_SET_EXPRESSIONS], left) {
43094313
if (i == NFT_SET_EXPR_MAX) {

net/netfilter/nft_dynset.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct nft_dynset {
1919
enum nft_registers sreg_key:8;
2020
enum nft_registers sreg_data:8;
2121
bool invert;
22+
bool expr;
2223
u8 num_exprs;
2324
u64 timeout;
2425
struct nft_expr *expr_array[NFT_SET_EXPR_MAX];
@@ -175,11 +176,12 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
175176

176177
if (tb[NFTA_DYNSET_FLAGS]) {
177178
u32 flags = ntohl(nla_get_be32(tb[NFTA_DYNSET_FLAGS]));
178-
179-
if (flags & ~NFT_DYNSET_F_INV)
180-
return -EINVAL;
179+
if (flags & ~(NFT_DYNSET_F_INV | NFT_DYNSET_F_EXPR))
180+
return -EOPNOTSUPP;
181181
if (flags & NFT_DYNSET_F_INV)
182182
priv->invert = true;
183+
if (flags & NFT_DYNSET_F_EXPR)
184+
priv->expr = true;
183185
}
184186

185187
set = nft_set_lookup_global(ctx->net, ctx->table,
@@ -210,7 +212,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
210212
timeout = 0;
211213
if (tb[NFTA_DYNSET_TIMEOUT] != NULL) {
212214
if (!(set->flags & NFT_SET_TIMEOUT))
213-
return -EINVAL;
215+
return -EOPNOTSUPP;
214216

215217
err = nf_msecs_to_jiffies64(tb[NFTA_DYNSET_TIMEOUT], &timeout);
216218
if (err)
@@ -224,7 +226,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
224226

225227
if (tb[NFTA_DYNSET_SREG_DATA] != NULL) {
226228
if (!(set->flags & NFT_SET_MAP))
227-
return -EINVAL;
229+
return -EOPNOTSUPP;
228230
if (set->dtype == NFT_DATA_VERDICT)
229231
return -EOPNOTSUPP;
230232

@@ -261,6 +263,9 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
261263
struct nlattr *tmp;
262264
int left;
263265

266+
if (!priv->expr)
267+
return -EINVAL;
268+
264269
i = 0;
265270
nla_for_each_nested(tmp, tb[NFTA_DYNSET_EXPRESSIONS], left) {
266271
if (i == NFT_SET_EXPR_MAX) {

net/netfilter/xt_RATEEST.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par)
115115
} cfg;
116116
int ret;
117117

118+
if (strnlen(info->name, sizeof(est->name)) >= sizeof(est->name))
119+
return -ENAMETOOLONG;
120+
118121
net_get_random_once(&jhash_rnd, sizeof(jhash_rnd));
119122

120123
mutex_lock(&xn->hash_lock);

0 commit comments

Comments
 (0)