Skip to content

Commit 7c87268

Browse files
committed
Merge: bpf: stable backports for 9.7 (phase 2)
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/7177 Depends: !7037 JIRA: https://issues.redhat.com/browse/RHEL-84579 JIRA: https://issues.redhat.com/browse/RHEL-101009 JIRA: https://issues.redhat.com/browse/RHEL-87910 CVE: CVE-2025-21867 CVE: CVE-2025-21997 Backporting fixes for serious issues from upstream. Signed-off-by: Felix Maurer <fmaurer@redhat.com> Approved-by: Murphy Zhou <xzhou@redhat.com> Approved-by: Guillaume Nault <gnault@redhat.com> Approved-by: Toke Høiland-Jørgensen <toke@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Jarod Wilson <jarod@redhat.com>
2 parents 2799918 + 7e05c15 commit 7c87268

File tree

9 files changed

+53
-14
lines changed

9 files changed

+53
-14
lines changed

include/net/sock.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2813,6 +2813,11 @@ static inline bool sk_is_udp(const struct sock *sk)
28132813
sk->sk_protocol == IPPROTO_UDP;
28142814
}
28152815

2816+
static inline bool sk_is_stream_unix(const struct sock *sk)
2817+
{
2818+
return sk->sk_family == AF_UNIX && sk->sk_type == SOCK_STREAM;
2819+
}
2820+
28162821
/**
28172822
* sk_eat_skb - Release a skb if it is no longer needed
28182823
* @sk: socket to eat this skb from

kernel/trace/bpf_trace.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3344,7 +3344,9 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
33443344
}
33453345

33463346
if (pid) {
3347+
rcu_read_lock();
33473348
task = get_pid_task(find_vpid(pid), PIDTYPE_TGID);
3349+
rcu_read_unlock();
33483350
if (!task) {
33493351
err = -ESRCH;
33503352
goto error_path_put;

net/bpf/test_run.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -647,12 +647,9 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size,
647647
void __user *data_in = u64_to_user_ptr(kattr->test.data_in);
648648
void *data;
649649

650-
if (size < ETH_HLEN || size > PAGE_SIZE - headroom - tailroom)
650+
if (user_size < ETH_HLEN || user_size > PAGE_SIZE - headroom - tailroom)
651651
return ERR_PTR(-EINVAL);
652652

653-
if (user_size > size)
654-
return ERR_PTR(-EMSGSIZE);
655-
656653
size = SKB_DATA_ALIGN(size);
657654
data = kzalloc(size + headroom + tailroom, GFP_USER);
658655
if (!data)

net/core/filter.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3197,6 +3197,13 @@ static const struct bpf_func_proto bpf_skb_vlan_pop_proto = {
31973197
.arg1_type = ARG_PTR_TO_CTX,
31983198
};
31993199

3200+
static void bpf_skb_change_protocol(struct sk_buff *skb, u16 proto)
3201+
{
3202+
skb->protocol = htons(proto);
3203+
if (skb_valid_dst(skb))
3204+
skb_dst_drop(skb);
3205+
}
3206+
32003207
static int bpf_skb_generic_push(struct sk_buff *skb, u32 off, u32 len)
32013208
{
32023209
/* Caller already did skb_cow() with len as headroom,
@@ -3293,7 +3300,7 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb)
32933300
}
32943301
}
32953302

3296-
skb->protocol = htons(ETH_P_IPV6);
3303+
bpf_skb_change_protocol(skb, ETH_P_IPV6);
32973304
skb_clear_hash(skb);
32983305

32993306
return 0;
@@ -3323,7 +3330,7 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb)
33233330
}
33243331
}
33253332

3326-
skb->protocol = htons(ETH_P_IP);
3333+
bpf_skb_change_protocol(skb, ETH_P_IP);
33273334
skb_clear_hash(skb);
33283335

33293336
return 0;
@@ -3514,10 +3521,10 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff,
35143521
/* Match skb->protocol to new outer l3 protocol */
35153522
if (skb->protocol == htons(ETH_P_IP) &&
35163523
flags & BPF_F_ADJ_ROOM_ENCAP_L3_IPV6)
3517-
skb->protocol = htons(ETH_P_IPV6);
3524+
bpf_skb_change_protocol(skb, ETH_P_IPV6);
35183525
else if (skb->protocol == htons(ETH_P_IPV6) &&
35193526
flags & BPF_F_ADJ_ROOM_ENCAP_L3_IPV4)
3520-
skb->protocol = htons(ETH_P_IP);
3527+
bpf_skb_change_protocol(skb, ETH_P_IP);
35213528
}
35223529

35233530
if (skb_is_gso(skb)) {
@@ -3570,10 +3577,10 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 off, u32 len_diff,
35703577
/* Match skb->protocol to new outer l3 protocol */
35713578
if (skb->protocol == htons(ETH_P_IP) &&
35723579
flags & BPF_F_ADJ_ROOM_DECAP_L3_IPV6)
3573-
skb->protocol = htons(ETH_P_IPV6);
3580+
bpf_skb_change_protocol(skb, ETH_P_IPV6);
35743581
else if (skb->protocol == htons(ETH_P_IPV6) &&
35753582
flags & BPF_F_ADJ_ROOM_DECAP_L3_IPV4)
3576-
skb->protocol = htons(ETH_P_IP);
3583+
bpf_skb_change_protocol(skb, ETH_P_IP);
35773584

35783585
if (skb_is_gso(skb)) {
35793586
struct skb_shared_info *shinfo = skb_shinfo(skb);

net/core/skmsg.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,13 @@ static void sk_psock_backlog(struct work_struct *work)
647647
u32 len, off;
648648
int ret;
649649

650+
/* Increment the psock refcnt to synchronize with close(fd) path in
651+
* sock_map_close(), ensuring we wait for backlog thread completion
652+
* before sk_socket freed. If refcnt increment fails, it indicates
653+
* sock_map_close() completed with sk_socket potentially already freed.
654+
*/
655+
if (!sk_psock_get(psock->sk))
656+
return;
650657
mutex_lock(&psock->work_mutex);
651658
if (unlikely(state->skb)) {
652659
spin_lock_bh(&psock->ingress_lock);
@@ -697,6 +704,7 @@ static void sk_psock_backlog(struct work_struct *work)
697704
}
698705
end:
699706
mutex_unlock(&psock->work_mutex);
707+
sk_psock_put(psock->sk, psock);
700708
}
701709

702710
struct sk_psock *sk_psock_init(struct sock *sk, int node)

net/core/sock_map.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,8 @@ static bool sock_map_sk_state_allowed(const struct sock *sk)
538538
{
539539
if (sk_is_tcp(sk))
540540
return (1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_LISTEN);
541+
if (sk_is_stream_unix(sk))
542+
return (1 << sk->sk_state) & TCPF_ESTABLISHED;
541543
return true;
542544
}
543545

net/unix/unix_bpf.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,15 +162,30 @@ int unix_stream_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool r
162162
{
163163
struct sock *sk_pair;
164164

165+
/* Restore does not decrement the sk_pair reference yet because we must
166+
* keep the a reference to the socket until after an RCU grace period
167+
* and any pending sends have completed.
168+
*/
165169
if (restore) {
166170
sk->sk_write_space = psock->saved_write_space;
167171
sock_replace_proto(sk, psock->sk_proto);
168172
return 0;
169173
}
170174

171-
sk_pair = unix_peer(sk);
172-
sock_hold(sk_pair);
173-
psock->sk_pair = sk_pair;
175+
/* psock_update_sk_prot can be called multiple times if psock is
176+
* added to multiple maps and/or slots in the same map. There is
177+
* also an edge case where replacing a psock with itself can trigger
178+
* an extra psock_update_sk_prot during the insert process. So it
179+
* must be safe to do multiple calls. Here we need to ensure we don't
180+
* increment the refcnt through sock_hold many times. There will only
181+
* be a single matching destroy operation.
182+
*/
183+
if (!psock->sk_pair) {
184+
sk_pair = unix_peer(sk);
185+
sock_hold(sk_pair);
186+
psock->sk_pair = sk_pair;
187+
}
188+
174189
unix_stream_bpf_check_needs_rebuild(psock->sk_proto);
175190
sock_replace_proto(sk, &unix_stream_bpf_prot);
176191
return 0;

net/xdp/xsk_buff_pool.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs,
106106
if (pool->unaligned)
107107
pool->free_heads[i] = xskb;
108108
else
109-
xp_init_xskb_addr(xskb, pool, i * pool->chunk_size);
109+
xp_init_xskb_addr(xskb, pool, (u64)i * pool->chunk_size);
110110
}
111111

112112
return pool;

net/xdp/xsk_diag.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ static int xsk_diag_fill(struct sock *sk, struct sk_buff *nlskb,
111111
sock_diag_save_cookie(sk, msg->xdiag_cookie);
112112

113113
mutex_lock(&xs->mutex);
114+
if (READ_ONCE(xs->state) == XSK_UNBOUND)
115+
goto out_nlmsg_trim;
116+
114117
if ((req->xdiag_show & XDP_SHOW_INFO) && xsk_diag_put_info(xs, nlskb))
115118
goto out_nlmsg_trim;
116119

0 commit comments

Comments
 (0)