Skip to content

Commit 4de75d3

Browse files
committed
Merge tag 'nf-23-12-06' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf
Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains Netfilter fixes for net: 1) Incorrect nf_defrag registration for bpf link infra, from D. Wythe. 2) Skip inactive elements in pipapo set backend walk to avoid double deactivation, from Florian Westphal. 3) Fix NFT_*_F_PRESENT check with big endian arch, also from Florian. 4) Bail out if number of expressions in NFTA_DYNSET_EXPRESSIONS mismatch stateful expressions in set declaration. 5) Honor family in table lookup by handle. Broken since 4.16. 6) Use sk_callback_lock to protect access to sk->sk_socket in xt_owner. sock_orphan() might zap this pointer, from Phil Sutter. All of these fixes address broken stuff for several releases. * tag 'nf-23-12-06' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: netfilter: xt_owner: Fix for unsafe access of sk->sk_socket netfilter: nf_tables: validate family when identifying table via handle netfilter: nf_tables: bail out on mismatching dynset and set expressions netfilter: nf_tables: fix 'exist' matching on bigendian arches netfilter: nft_set_pipapo: skip inactive elements during set walk netfilter: bpf: fix bad registration on nf_defrag ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents c85e559 + 7ae836a commit 4de75d3

File tree

7 files changed

+40
-19
lines changed

7 files changed

+40
-19
lines changed

net/netfilter/nf_bpf_link.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,23 @@ struct bpf_nf_link {
3131
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) || IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
3232
static const struct nf_defrag_hook *
3333
get_proto_defrag_hook(struct bpf_nf_link *link,
34-
const struct nf_defrag_hook __rcu *global_hook,
34+
const struct nf_defrag_hook __rcu **ptr_global_hook,
3535
const char *mod)
3636
{
3737
const struct nf_defrag_hook *hook;
3838
int err;
3939

4040
/* RCU protects us from races against module unloading */
4141
rcu_read_lock();
42-
hook = rcu_dereference(global_hook);
42+
hook = rcu_dereference(*ptr_global_hook);
4343
if (!hook) {
4444
rcu_read_unlock();
4545
err = request_module(mod);
4646
if (err)
4747
return ERR_PTR(err < 0 ? err : -EINVAL);
4848

4949
rcu_read_lock();
50-
hook = rcu_dereference(global_hook);
50+
hook = rcu_dereference(*ptr_global_hook);
5151
}
5252

5353
if (hook && try_module_get(hook->owner)) {
@@ -78,7 +78,7 @@ static int bpf_nf_enable_defrag(struct bpf_nf_link *link)
7878
switch (link->hook_ops.pf) {
7979
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
8080
case NFPROTO_IPV4:
81-
hook = get_proto_defrag_hook(link, nf_defrag_v4_hook, "nf_defrag_ipv4");
81+
hook = get_proto_defrag_hook(link, &nf_defrag_v4_hook, "nf_defrag_ipv4");
8282
if (IS_ERR(hook))
8383
return PTR_ERR(hook);
8484

@@ -87,7 +87,7 @@ static int bpf_nf_enable_defrag(struct bpf_nf_link *link)
8787
#endif
8888
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
8989
case NFPROTO_IPV6:
90-
hook = get_proto_defrag_hook(link, nf_defrag_v6_hook, "nf_defrag_ipv6");
90+
hook = get_proto_defrag_hook(link, &nf_defrag_v6_hook, "nf_defrag_ipv6");
9191
if (IS_ERR(hook))
9292
return PTR_ERR(hook);
9393

net/netfilter/nf_tables_api.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -803,14 +803,15 @@ static struct nft_table *nft_table_lookup(const struct net *net,
803803

804804
static struct nft_table *nft_table_lookup_byhandle(const struct net *net,
805805
const struct nlattr *nla,
806-
u8 genmask, u32 nlpid)
806+
int family, u8 genmask, u32 nlpid)
807807
{
808808
struct nftables_pernet *nft_net;
809809
struct nft_table *table;
810810

811811
nft_net = nft_pernet(net);
812812
list_for_each_entry(table, &nft_net->tables, list) {
813813
if (be64_to_cpu(nla_get_be64(nla)) == table->handle &&
814+
table->family == family &&
814815
nft_active_genmask(table, genmask)) {
815816
if (nft_table_has_owner(table) &&
816817
nlpid && table->nlpid != nlpid)
@@ -1544,7 +1545,7 @@ static int nf_tables_deltable(struct sk_buff *skb, const struct nfnl_info *info,
15441545

15451546
if (nla[NFTA_TABLE_HANDLE]) {
15461547
attr = nla[NFTA_TABLE_HANDLE];
1547-
table = nft_table_lookup_byhandle(net, attr, genmask,
1548+
table = nft_table_lookup_byhandle(net, attr, family, genmask,
15481549
NETLINK_CB(skb).portid);
15491550
} else {
15501551
attr = nla[NFTA_TABLE_NAME];

net/netfilter/nft_dynset.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,10 +280,15 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
280280
priv->expr_array[i] = dynset_expr;
281281
priv->num_exprs++;
282282

283-
if (set->num_exprs &&
284-
dynset_expr->ops != set->exprs[i]->ops) {
285-
err = -EOPNOTSUPP;
286-
goto err_expr_free;
283+
if (set->num_exprs) {
284+
if (i >= set->num_exprs) {
285+
err = -EINVAL;
286+
goto err_expr_free;
287+
}
288+
if (dynset_expr->ops != set->exprs[i]->ops) {
289+
err = -EOPNOTSUPP;
290+
goto err_expr_free;
291+
}
287292
}
288293
i++;
289294
}

net/netfilter/nft_exthdr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ static void nft_exthdr_tcp_eval(const struct nft_expr *expr,
214214

215215
offset = i + priv->offset;
216216
if (priv->flags & NFT_EXTHDR_F_PRESENT) {
217-
*dest = 1;
217+
nft_reg_store8(dest, 1);
218218
} else {
219219
if (priv->len % NFT_REG32_SIZE)
220220
dest[priv->len / NFT_REG32_SIZE] = 0;
@@ -461,7 +461,7 @@ static void nft_exthdr_dccp_eval(const struct nft_expr *expr,
461461
type = bufp[0];
462462

463463
if (type == priv->type) {
464-
*dest = 1;
464+
nft_reg_store8(dest, 1);
465465
return;
466466
}
467467

net/netfilter/nft_fib.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,15 @@ void nft_fib_store_result(void *reg, const struct nft_fib *priv,
145145
switch (priv->result) {
146146
case NFT_FIB_RESULT_OIF:
147147
index = dev ? dev->ifindex : 0;
148-
*dreg = (priv->flags & NFTA_FIB_F_PRESENT) ? !!index : index;
148+
if (priv->flags & NFTA_FIB_F_PRESENT)
149+
nft_reg_store8(dreg, !!index);
150+
else
151+
*dreg = index;
152+
149153
break;
150154
case NFT_FIB_RESULT_OIFNAME:
151155
if (priv->flags & NFTA_FIB_F_PRESENT)
152-
*dreg = !!dev;
156+
nft_reg_store8(dreg, !!dev);
153157
else
154158
strscpy_pad(reg, dev ? dev->name : "", IFNAMSIZ);
155159
break;

net/netfilter/nft_set_pipapo.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2043,6 +2043,9 @@ static void nft_pipapo_walk(const struct nft_ctx *ctx, struct nft_set *set,
20432043

20442044
e = f->mt[r].e;
20452045

2046+
if (!nft_set_elem_active(&e->ext, iter->genmask))
2047+
goto cont;
2048+
20462049
iter->err = iter->fn(ctx, set, iter, &e->priv);
20472050
if (iter->err < 0)
20482051
goto out;

net/netfilter/xt_owner.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,18 +76,23 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
7676
*/
7777
return false;
7878

79-
filp = sk->sk_socket->file;
80-
if (filp == NULL)
79+
read_lock_bh(&sk->sk_callback_lock);
80+
filp = sk->sk_socket ? sk->sk_socket->file : NULL;
81+
if (filp == NULL) {
82+
read_unlock_bh(&sk->sk_callback_lock);
8183
return ((info->match ^ info->invert) &
8284
(XT_OWNER_UID | XT_OWNER_GID)) == 0;
85+
}
8386

8487
if (info->match & XT_OWNER_UID) {
8588
kuid_t uid_min = make_kuid(net->user_ns, info->uid_min);
8689
kuid_t uid_max = make_kuid(net->user_ns, info->uid_max);
8790
if ((uid_gte(filp->f_cred->fsuid, uid_min) &&
8891
uid_lte(filp->f_cred->fsuid, uid_max)) ^
89-
!(info->invert & XT_OWNER_UID))
92+
!(info->invert & XT_OWNER_UID)) {
93+
read_unlock_bh(&sk->sk_callback_lock);
9094
return false;
95+
}
9196
}
9297

9398
if (info->match & XT_OWNER_GID) {
@@ -112,10 +117,13 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
112117
}
113118
}
114119

115-
if (match ^ !(info->invert & XT_OWNER_GID))
120+
if (match ^ !(info->invert & XT_OWNER_GID)) {
121+
read_unlock_bh(&sk->sk_callback_lock);
116122
return false;
123+
}
117124
}
118125

126+
read_unlock_bh(&sk->sk_callback_lock);
119127
return true;
120128
}
121129

0 commit comments

Comments
 (0)