Skip to content

Commit e93c261

Browse files
author
CKI KWF Bot
committed
Merge: netfilter: stable backport for 9.8 phase 2
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/7424 JIRA: https://issues.redhat.com/browse/RHEL-115630 This series backports bug fixes from upstream. Signed-off-by: Florian Westphal <fwestpha@redhat.com> Approved-by: Murphy Zhou <xzhou@redhat.com> Approved-by: Phil Sutter <psutter@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
2 parents a10ae69 + 2042372 commit e93c261

File tree

13 files changed

+112
-84
lines changed

13 files changed

+112
-84
lines changed

include/net/netfilter/nf_flow_table.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ static inline __be16 __nf_flow_pppoe_proto(const struct sk_buff *skb)
353353

354354
static inline bool nf_flow_pppoe_proto(struct sk_buff *skb, __be16 *inner_proto)
355355
{
356-
if (!pskb_may_pull(skb, PPPOE_SES_HLEN))
356+
if (!pskb_may_pull(skb, ETH_HLEN + PPPOE_SES_HLEN))
357357
return false;
358358

359359
*inner_proto = __nf_flow_pppoe_proto(skb);

net/bridge/netfilter/nf_conntrack_bridge.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,19 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk,
6060
struct ip_fraglist_iter iter;
6161
struct sk_buff *frag;
6262

63-
if (first_len - hlen > mtu ||
64-
skb_headroom(skb) < ll_rs)
63+
if (first_len - hlen > mtu)
6564
goto blackhole;
6665

67-
if (skb_cloned(skb))
66+
if (skb_cloned(skb) ||
67+
skb_headroom(skb) < ll_rs)
6868
goto slow_path;
6969

7070
skb_walk_frags(skb, frag) {
71-
if (frag->len > mtu ||
72-
skb_headroom(frag) < hlen + ll_rs)
71+
if (frag->len > mtu)
7372
goto blackhole;
7473

75-
if (skb_shared(frag))
74+
if (skb_shared(frag) ||
75+
skb_headroom(frag) < hlen + ll_rs)
7676
goto slow_path;
7777
}
7878

net/ipv4/netfilter/nf_reject_ipv4.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,7 @@ void nf_send_reset(struct net *net, struct sock *sk, struct sk_buff *oldskb,
245245
if (!oth)
246246
return;
247247

248-
if ((hook == NF_INET_PRE_ROUTING || hook == NF_INET_INGRESS) &&
249-
nf_reject_fill_skb_dst(oldskb) < 0)
248+
if (!skb_dst(oldskb) && nf_reject_fill_skb_dst(oldskb) < 0)
250249
return;
251250

252251
if (skb_rtable(oldskb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
@@ -317,8 +316,7 @@ void nf_send_unreach(struct sk_buff *skb_in, int code, int hook)
317316
if (iph->frag_off & htons(IP_OFFSET))
318317
return;
319318

320-
if ((hook == NF_INET_PRE_ROUTING || hook == NF_INET_INGRESS) &&
321-
nf_reject_fill_skb_dst(skb_in) < 0)
319+
if (!skb_dst(skb_in) && nf_reject_fill_skb_dst(skb_in) < 0)
322320
return;
323321

324322
if (skb_csum_unnecessary(skb_in) || !nf_reject_verify_csum(proto)) {

net/ipv6/netfilter.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,20 +164,20 @@ int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
164164
struct ip6_fraglist_iter iter;
165165
struct sk_buff *frag2;
166166

167-
if (first_len - hlen > mtu ||
168-
skb_headroom(skb) < (hroom + sizeof(struct frag_hdr)))
167+
if (first_len - hlen > mtu)
169168
goto blackhole;
170169

171-
if (skb_cloned(skb))
170+
if (skb_cloned(skb) ||
171+
skb_headroom(skb) < (hroom + sizeof(struct frag_hdr)))
172172
goto slow_path;
173173

174174
skb_walk_frags(skb, frag2) {
175-
if (frag2->len > mtu ||
176-
skb_headroom(frag2) < (hlen + hroom + sizeof(struct frag_hdr)))
175+
if (frag2->len > mtu)
177176
goto blackhole;
178177

179178
/* Partially cloned skb? */
180-
if (skb_shared(frag2))
179+
if (skb_shared(frag2) ||
180+
skb_headroom(frag2) < (hlen + hroom + sizeof(struct frag_hdr)))
181181
goto slow_path;
182182
}
183183

net/ipv6/netfilter/nf_reject_ipv6.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
293293
fl6.fl6_sport = otcph->dest;
294294
fl6.fl6_dport = otcph->source;
295295

296-
if (hook == NF_INET_PRE_ROUTING || hook == NF_INET_INGRESS) {
296+
if (!skb_dst(oldskb)) {
297297
nf_ip6_route(net, &dst, flowi6_to_flowi(&fl6), false);
298298
if (!dst)
299299
return;
@@ -396,8 +396,7 @@ void nf_send_unreach6(struct net *net, struct sk_buff *skb_in,
396396
if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL)
397397
skb_in->dev = net->loopback_dev;
398398

399-
if ((hooknum == NF_INET_PRE_ROUTING || hooknum == NF_INET_INGRESS) &&
400-
nf_reject6_fill_skb_dst(skb_in) < 0)
399+
if (!skb_dst(skb_in) && nf_reject6_fill_skb_dst(skb_in) < 0)
401400
return;
402401

403402
icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0);

net/netfilter/ipvs/ip_vs_xmit.c

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,12 @@ __mtu_check_toobig_v6(const struct sk_buff *skb, u32 mtu)
119119
return false;
120120
}
121121

122-
/* Get route to daddr, update *saddr, optionally bind route to saddr */
122+
/* Get route to daddr, optionally bind route to saddr */
123123
static struct rtable *do_output_route4(struct net *net, __be32 daddr,
124-
int rt_mode, __be32 *saddr)
124+
int rt_mode, __be32 *ret_saddr)
125125
{
126126
struct flowi4 fl4;
127127
struct rtable *rt;
128-
bool loop = false;
129128

130129
memset(&fl4, 0, sizeof(fl4));
131130
fl4.daddr = daddr;
@@ -135,23 +134,17 @@ static struct rtable *do_output_route4(struct net *net, __be32 daddr,
135134
retry:
136135
rt = ip_route_output_key(net, &fl4);
137136
if (IS_ERR(rt)) {
138-
/* Invalid saddr ? */
139-
if (PTR_ERR(rt) == -EINVAL && *saddr &&
140-
rt_mode & IP_VS_RT_MODE_CONNECT && !loop) {
141-
*saddr = 0;
142-
flowi4_update_output(&fl4, 0, 0, daddr, 0);
143-
goto retry;
144-
}
145137
IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n", &daddr);
146138
return NULL;
147-
} else if (!*saddr && rt_mode & IP_VS_RT_MODE_CONNECT && fl4.saddr) {
139+
}
140+
if (rt_mode & IP_VS_RT_MODE_CONNECT && fl4.saddr) {
148141
ip_rt_put(rt);
149-
*saddr = fl4.saddr;
150142
flowi4_update_output(&fl4, 0, 0, daddr, fl4.saddr);
151-
loop = true;
143+
rt_mode = 0;
152144
goto retry;
153145
}
154-
*saddr = fl4.saddr;
146+
if (ret_saddr)
147+
*ret_saddr = fl4.saddr;
155148
return rt;
156149
}
157150

@@ -344,19 +337,15 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
344337
if (ret_saddr)
345338
*ret_saddr = dest_dst->dst_saddr.ip;
346339
} else {
347-
__be32 saddr = htonl(INADDR_ANY);
348-
349340
noref = 0;
350341

351342
/* For such unconfigured boxes avoid many route lookups
352343
* for performance reasons because we do not remember saddr
353344
*/
354345
rt_mode &= ~IP_VS_RT_MODE_CONNECT;
355-
rt = do_output_route4(net, daddr, rt_mode, &saddr);
346+
rt = do_output_route4(net, daddr, rt_mode, ret_saddr);
356347
if (!rt)
357348
goto err_unreach;
358-
if (ret_saddr)
359-
*ret_saddr = saddr;
360349
}
361350

362351
local = (rt->rt_flags & RTCF_LOCAL) ? 1 : 0;

net/netfilter/nf_bpf_link.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ static unsigned int nf_hook_run_bpf(void *bpf_prog, struct sk_buff *skb,
1515
.skb = skb,
1616
};
1717

18-
return bpf_prog_run(prog, &ctx);
18+
return bpf_prog_run_pin_on_cpu(prog, &ctx);
1919
}
2020

2121
struct bpf_nf_link {
@@ -200,6 +200,9 @@ static bool nf_is_valid_access(int off, int size, enum bpf_access_type type,
200200
if (off < 0 || off >= sizeof(struct bpf_nf_ctx))
201201
return false;
202202

203+
if (off % size != 0)
204+
return false;
205+
203206
if (type == BPF_WRITE)
204207
return false;
205208

net/netfilter/nf_conntrack_netlink.c

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -862,8 +862,6 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
862862

863863
static int ctnetlink_done(struct netlink_callback *cb)
864864
{
865-
if (cb->args[1])
866-
nf_ct_put((struct nf_conn *)cb->args[1]);
867865
kfree(cb->data);
868866
return 0;
869867
}
@@ -1178,19 +1176,26 @@ static int ctnetlink_filter_match(struct nf_conn *ct, void *data)
11781176
return 0;
11791177
}
11801178

1179+
static unsigned long ctnetlink_get_id(const struct nf_conn *ct)
1180+
{
1181+
unsigned long id = nf_ct_get_id(ct);
1182+
1183+
return id ? id : 1;
1184+
}
1185+
11811186
static int
11821187
ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
11831188
{
11841189
unsigned int flags = cb->data ? NLM_F_DUMP_FILTERED : 0;
11851190
struct net *net = sock_net(skb->sk);
1186-
struct nf_conn *ct, *last;
1191+
unsigned long last_id = cb->args[1];
11871192
struct nf_conntrack_tuple_hash *h;
11881193
struct hlist_nulls_node *n;
11891194
struct nf_conn *nf_ct_evict[8];
1195+
struct nf_conn *ct;
11901196
int res, i;
11911197
spinlock_t *lockp;
11921198

1193-
last = (struct nf_conn *)cb->args[1];
11941199
i = 0;
11951200

11961201
local_bh_disable();
@@ -1227,7 +1232,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
12271232
continue;
12281233

12291234
if (cb->args[1]) {
1230-
if (ct != last)
1235+
if (ctnetlink_get_id(ct) != last_id)
12311236
continue;
12321237
cb->args[1] = 0;
12331238
}
@@ -1240,8 +1245,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
12401245
NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
12411246
ct, true, flags);
12421247
if (res < 0) {
1243-
nf_conntrack_get(&ct->ct_general);
1244-
cb->args[1] = (unsigned long)ct;
1248+
cb->args[1] = ctnetlink_get_id(ct);
12451249
spin_unlock(lockp);
12461250
goto out;
12471251
}
@@ -1254,12 +1258,10 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
12541258
}
12551259
out:
12561260
local_bh_enable();
1257-
if (last) {
1261+
if (last_id) {
12581262
/* nf ct hash resize happened, now clear the leftover. */
1259-
if ((struct nf_conn *)cb->args[1] == last)
1263+
if (cb->args[1] == last_id)
12601264
cb->args[1] = 0;
1261-
1262-
nf_ct_put(last);
12631265
}
12641266

12651267
while (i) {
@@ -3153,23 +3155,27 @@ ctnetlink_expect_event(unsigned int events, const struct nf_exp_event *item)
31533155
return 0;
31543156
}
31553157
#endif
3156-
static int ctnetlink_exp_done(struct netlink_callback *cb)
3158+
3159+
static unsigned long ctnetlink_exp_id(const struct nf_conntrack_expect *exp)
31573160
{
3158-
if (cb->args[1])
3159-
nf_ct_expect_put((struct nf_conntrack_expect *)cb->args[1]);
3160-
return 0;
3161+
unsigned long id = (unsigned long)exp;
3162+
3163+
id += nf_ct_get_id(exp->master);
3164+
id += exp->class;
3165+
3166+
return id ? id : 1;
31613167
}
31623168

31633169
static int
31643170
ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
31653171
{
31663172
struct net *net = sock_net(skb->sk);
3167-
struct nf_conntrack_expect *exp, *last;
31683173
struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
31693174
u_int8_t l3proto = nfmsg->nfgen_family;
3175+
unsigned long last_id = cb->args[1];
3176+
struct nf_conntrack_expect *exp;
31703177

31713178
rcu_read_lock();
3172-
last = (struct nf_conntrack_expect *)cb->args[1];
31733179
for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) {
31743180
restart:
31753181
hlist_for_each_entry_rcu(exp, &nf_ct_expect_hash[cb->args[0]],
@@ -3181,7 +3187,7 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
31813187
continue;
31823188

31833189
if (cb->args[1]) {
3184-
if (exp != last)
3190+
if (ctnetlink_exp_id(exp) != last_id)
31853191
continue;
31863192
cb->args[1] = 0;
31873193
}
@@ -3190,9 +3196,7 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
31903196
cb->nlh->nlmsg_seq,
31913197
IPCTNL_MSG_EXP_NEW,
31923198
exp) < 0) {
3193-
if (!refcount_inc_not_zero(&exp->use))
3194-
continue;
3195-
cb->args[1] = (unsigned long)exp;
3199+
cb->args[1] = ctnetlink_exp_id(exp);
31963200
goto out;
31973201
}
31983202
}
@@ -3203,42 +3207,38 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
32033207
}
32043208
out:
32053209
rcu_read_unlock();
3206-
if (last)
3207-
nf_ct_expect_put(last);
3208-
32093210
return skb->len;
32103211
}
32113212

32123213
static int
32133214
ctnetlink_exp_ct_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
32143215
{
3215-
struct nf_conntrack_expect *exp, *last;
32163216
struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
32173217
struct nf_conn *ct = cb->data;
32183218
struct nf_conn_help *help = nfct_help(ct);
32193219
u_int8_t l3proto = nfmsg->nfgen_family;
3220+
unsigned long last_id = cb->args[1];
3221+
struct nf_conntrack_expect *exp;
32203222

32213223
if (cb->args[0])
32223224
return 0;
32233225

32243226
rcu_read_lock();
3225-
last = (struct nf_conntrack_expect *)cb->args[1];
3227+
32263228
restart:
32273229
hlist_for_each_entry_rcu(exp, &help->expectations, lnode) {
32283230
if (l3proto && exp->tuple.src.l3num != l3proto)
32293231
continue;
32303232
if (cb->args[1]) {
3231-
if (exp != last)
3233+
if (ctnetlink_exp_id(exp) != last_id)
32323234
continue;
32333235
cb->args[1] = 0;
32343236
}
32353237
if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).portid,
32363238
cb->nlh->nlmsg_seq,
32373239
IPCTNL_MSG_EXP_NEW,
32383240
exp) < 0) {
3239-
if (!refcount_inc_not_zero(&exp->use))
3240-
continue;
3241-
cb->args[1] = (unsigned long)exp;
3241+
cb->args[1] = ctnetlink_exp_id(exp);
32423242
goto out;
32433243
}
32443244
}
@@ -3249,9 +3249,6 @@ ctnetlink_exp_ct_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
32493249
cb->args[0] = 1;
32503250
out:
32513251
rcu_read_unlock();
3252-
if (last)
3253-
nf_ct_expect_put(last);
3254-
32553252
return skb->len;
32563253
}
32573254

@@ -3270,7 +3267,6 @@ static int ctnetlink_dump_exp_ct(struct net *net, struct sock *ctnl,
32703267
struct nf_conntrack_zone zone;
32713268
struct netlink_dump_control c = {
32723269
.dump = ctnetlink_exp_ct_dump_table,
3273-
.done = ctnetlink_exp_done,
32743270
};
32753271

32763272
err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER,
@@ -3320,7 +3316,6 @@ static int ctnetlink_get_expect(struct sk_buff *skb,
33203316
else {
33213317
struct netlink_dump_control c = {
33223318
.dump = ctnetlink_exp_dump_table,
3323-
.done = ctnetlink_exp_done,
33243319
};
33253320
return netlink_dump_start(info->sk, skb, info->nlh, &c);
33263321
}

net/netfilter/nf_nat_core.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,8 +544,11 @@ static void nf_nat_l4proto_unique_tuple(struct nf_conntrack_tuple *tuple,
544544
find_free_id:
545545
if (range->flags & NF_NAT_RANGE_PROTO_OFFSET)
546546
off = (ntohs(*keyptr) - ntohs(range->base_proto.all));
547-
else
547+
else if ((range->flags & NF_NAT_RANGE_PROTO_RANDOM_ALL) ||
548+
maniptype != NF_NAT_MANIP_DST)
548549
off = prandom_u32();
550+
else
551+
off = 0;
549552

550553
attempts = range_size;
551554
if (attempts > NF_NAT_MAX_ATTEMPTS)

0 commit comments

Comments
 (0)