Skip to content

Commit 9c707ba

Browse files
committed
Merge tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Pull BPF fixes from Daniel Borkmann: - Fix inlining of bpf_get_smp_processor_id helper for !CONFIG_SMP systems (Andrea Righi) - Fix BPF USDT selftests helper code to use asm constraint "m" for LoongArch (Tiezhu Yang) - Fix BPF selftest compilation error in get_uprobe_offset when PROCMAP_QUERY is not defined (Jerome Marchand) - Fix BPF bpf_skb_change_tail helper when used in context of BPF sockmap to handle negative skb header offsets (Cong Wang) - Several fixes to BPF sockmap code, among others, in the area of socket buffer accounting (Levi Zim, Zijian Zhang, Cong Wang) * tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf: selftests/bpf: Test bpf_skb_change_tail() in TC ingress selftests/bpf: Introduce socket_helpers.h for TC tests selftests/bpf: Add a BPF selftest for bpf_skb_change_tail() bpf: Check negative offsets in __bpf_skb_min_len() tcp_bpf: Fix copied value in tcp_bpf_sendmsg skmsg: Return copied bytes in sk_msg_memcopy_from_iter tcp_bpf: Add sk_rmem_alloc related logic for tcp_bpf ingress redirection tcp_bpf: Charge receive socket buffer in bpf_tcp_ingress() selftests/bpf: Fix compilation error in get_uprobe_offset() selftests/bpf: Use asm constraint "m" for LoongArch bpf: Fix bpf_get_smp_processor_id() on !CONFIG_SMP
2 parents 876685c + 4a58963 commit 9c707ba

File tree

14 files changed

+712
-405
lines changed

14 files changed

+712
-405
lines changed

include/linux/skmsg.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,17 +317,22 @@ static inline void sock_drop(struct sock *sk, struct sk_buff *skb)
317317
kfree_skb(skb);
318318
}
319319

320-
static inline void sk_psock_queue_msg(struct sk_psock *psock,
320+
static inline bool sk_psock_queue_msg(struct sk_psock *psock,
321321
struct sk_msg *msg)
322322
{
323+
bool ret;
324+
323325
spin_lock_bh(&psock->ingress_lock);
324-
if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED))
326+
if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) {
325327
list_add_tail(&msg->list, &psock->ingress_msg);
326-
else {
328+
ret = true;
329+
} else {
327330
sk_msg_free(psock->sk, msg);
328331
kfree(msg);
332+
ret = false;
329333
}
330334
spin_unlock_bh(&psock->ingress_lock);
335+
return ret;
331336
}
332337

333338
static inline struct sk_msg *sk_psock_dequeue_msg(struct sk_psock *psock)

include/net/sock.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,15 +1527,21 @@ static inline bool sk_wmem_schedule(struct sock *sk, int size)
15271527
}
15281528

15291529
static inline bool
1530-
sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, int size)
1530+
__sk_rmem_schedule(struct sock *sk, int size, bool pfmemalloc)
15311531
{
15321532
int delta;
15331533

15341534
if (!sk_has_account(sk))
15351535
return true;
15361536
delta = size - sk->sk_forward_alloc;
15371537
return delta <= 0 || __sk_mem_schedule(sk, delta, SK_MEM_RECV) ||
1538-
skb_pfmemalloc(skb);
1538+
pfmemalloc;
1539+
}
1540+
1541+
static inline bool
1542+
sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, int size)
1543+
{
1544+
return __sk_rmem_schedule(sk, size, skb_pfmemalloc(skb));
15391545
}
15401546

15411547
static inline int sk_unused_reserved_mem(const struct sock *sk)

kernel/bpf/verifier.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21281,11 +21281,15 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
2128121281
* changed in some incompatible and hard to support
2128221282
* way, it's fine to back out this inlining logic
2128321283
*/
21284+
#ifdef CONFIG_SMP
2128421285
insn_buf[0] = BPF_MOV32_IMM(BPF_REG_0, (u32)(unsigned long)&pcpu_hot.cpu_number);
2128521286
insn_buf[1] = BPF_MOV64_PERCPU_REG(BPF_REG_0, BPF_REG_0);
2128621287
insn_buf[2] = BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0);
2128721288
cnt = 3;
21288-
21289+
#else
21290+
insn_buf[0] = BPF_ALU32_REG(BPF_XOR, BPF_REG_0, BPF_REG_0);
21291+
cnt = 1;
21292+
#endif
2128921293
new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt);
2129021294
if (!new_prog)
2129121295
return -ENOMEM;

net/core/filter.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3734,13 +3734,22 @@ static const struct bpf_func_proto bpf_skb_adjust_room_proto = {
37343734

37353735
static u32 __bpf_skb_min_len(const struct sk_buff *skb)
37363736
{
3737-
u32 min_len = skb_network_offset(skb);
3737+
int offset = skb_network_offset(skb);
3738+
u32 min_len = 0;
37383739

3739-
if (skb_transport_header_was_set(skb))
3740-
min_len = skb_transport_offset(skb);
3741-
if (skb->ip_summed == CHECKSUM_PARTIAL)
3742-
min_len = skb_checksum_start_offset(skb) +
3743-
skb->csum_offset + sizeof(__sum16);
3740+
if (offset > 0)
3741+
min_len = offset;
3742+
if (skb_transport_header_was_set(skb)) {
3743+
offset = skb_transport_offset(skb);
3744+
if (offset > 0)
3745+
min_len = offset;
3746+
}
3747+
if (skb->ip_summed == CHECKSUM_PARTIAL) {
3748+
offset = skb_checksum_start_offset(skb) +
3749+
skb->csum_offset + sizeof(__sum16);
3750+
if (offset > 0)
3751+
min_len = offset;
3752+
}
37443753
return min_len;
37453754
}
37463755

net/core/skmsg.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,8 @@ int sk_msg_memcopy_from_iter(struct sock *sk, struct iov_iter *from,
369369
struct sk_msg *msg, u32 bytes)
370370
{
371371
int ret = -ENOSPC, i = msg->sg.curr;
372+
u32 copy, buf_size, copied = 0;
372373
struct scatterlist *sge;
373-
u32 copy, buf_size;
374374
void *to;
375375

376376
do {
@@ -397,14 +397,15 @@ int sk_msg_memcopy_from_iter(struct sock *sk, struct iov_iter *from,
397397
goto out;
398398
}
399399
bytes -= copy;
400+
copied += copy;
400401
if (!bytes)
401402
break;
402403
msg->sg.copybreak = 0;
403404
sk_msg_iter_var_next(i);
404405
} while (i != msg->sg.end);
405406
out:
406407
msg->sg.curr = i;
407-
return ret;
408+
return (ret < 0) ? ret : copied;
408409
}
409410
EXPORT_SYMBOL_GPL(sk_msg_memcopy_from_iter);
410411

@@ -445,8 +446,10 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
445446
if (likely(!peek)) {
446447
sge->offset += copy;
447448
sge->length -= copy;
448-
if (!msg_rx->skb)
449+
if (!msg_rx->skb) {
449450
sk_mem_uncharge(sk, copy);
451+
atomic_sub(copy, &sk->sk_rmem_alloc);
452+
}
450453
msg_rx->sg.size -= copy;
451454

452455
if (!sge->length) {
@@ -772,6 +775,8 @@ static void __sk_psock_purge_ingress_msg(struct sk_psock *psock)
772775

773776
list_for_each_entry_safe(msg, tmp, &psock->ingress_msg, list) {
774777
list_del(&msg->list);
778+
if (!msg->skb)
779+
atomic_sub(msg->sg.size, &psock->sk->sk_rmem_alloc);
775780
sk_msg_free(psock->sk, msg);
776781
kfree(msg);
777782
}

net/ipv4/tcp_bpf.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,14 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock,
4949
sge = sk_msg_elem(msg, i);
5050
size = (apply && apply_bytes < sge->length) ?
5151
apply_bytes : sge->length;
52-
if (!sk_wmem_schedule(sk, size)) {
52+
if (!__sk_rmem_schedule(sk, size, false)) {
5353
if (!copied)
5454
ret = -ENOMEM;
5555
break;
5656
}
5757

5858
sk_mem_charge(sk, size);
59+
atomic_add(size, &sk->sk_rmem_alloc);
5960
sk_msg_xfer(tmp, msg, i, size);
6061
copied += size;
6162
if (sge->length)
@@ -74,7 +75,8 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock,
7475

7576
if (!ret) {
7677
msg->sg.start = i;
77-
sk_psock_queue_msg(psock, tmp);
78+
if (!sk_psock_queue_msg(psock, tmp))
79+
atomic_sub(copied, &sk->sk_rmem_alloc);
7880
sk_psock_data_ready(sk, psock);
7981
} else {
8082
sk_msg_free(sk, tmp);
@@ -493,7 +495,7 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock,
493495
static int tcp_bpf_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
494496
{
495497
struct sk_msg tmp, *msg_tx = NULL;
496-
int copied = 0, err = 0;
498+
int copied = 0, err = 0, ret = 0;
497499
struct sk_psock *psock;
498500
long timeo;
499501
int flags;
@@ -536,14 +538,14 @@ static int tcp_bpf_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
536538
copy = msg_tx->sg.size - osize;
537539
}
538540

539-
err = sk_msg_memcopy_from_iter(sk, &msg->msg_iter, msg_tx,
541+
ret = sk_msg_memcopy_from_iter(sk, &msg->msg_iter, msg_tx,
540542
copy);
541-
if (err < 0) {
543+
if (ret < 0) {
542544
sk_msg_trim(sk, msg_tx, osize);
543545
goto out_err;
544546
}
545547

546-
copied += copy;
548+
copied += ret;
547549
if (psock->cork_bytes) {
548550
if (size > psock->cork_bytes)
549551
psock->cork_bytes = 0;

0 commit comments

Comments
 (0)