Skip to content

Commit 7671b02

Browse files
committed
Daniel Borkmann says: ==================== pull-request: bpf 2021-10-07 We've added 7 non-merge commits during the last 8 day(s) which contain a total of 8 files changed, 38 insertions(+), 21 deletions(-). The main changes are: 1) Fix ARM BPF JIT to preserve caller-saved regs for DIV/MOD JIT-internal helper call, from Johan Almbladh. 2) Fix integer overflow in BPF stack map element size calculation when used with preallocation, from Tatsuhiko Yasumatsu. 3) Fix an AF_UNIX regression due to added BPF sockmap support related to shutdown handling, from Jiang Wang. 4) Fix a segfault in libbpf when generating light skeletons from objects without BTF, from Kumar Kartikeya Dwivedi. 5) Fix a libbpf memory leak in strset to free the actual struct strset itself, from Andrii Nakryiko. 6) Dual-license bpf_insn.h similarly as we did for libbpf and bpftool, with ACKs from all contributors, from Luca Boccassi. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 578f393 + d0c6416 commit 7671b02

File tree

8 files changed

+38
-21
lines changed

8 files changed

+38
-21
lines changed

arch/arm/net/bpf_jit_32.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
* +-----+
3737
* |RSVD | JIT scratchpad
3838
* current ARM_SP => +-----+ <= (BPF_FP - STACK_SIZE + SCRATCH_SIZE)
39+
* | ... | caller-saved registers
40+
* +-----+
41+
* | ... | arguments passed on stack
42+
* ARM_SP during call => +-----|
3943
* | |
4044
* | ... | Function call stack
4145
* | |
@@ -63,13 +67,21 @@
6367
*
6468
* When popping registers off the stack at the end of a BPF function, we
6569
* reference them via the current ARM_FP register.
70+
*
71+
* Some eBPF operations are implemented via a call to a helper function.
72+
* Such calls are "invisible" in the eBPF code, so it is up to the calling
73+
* program to preserve any caller-saved ARM registers during the call. The
74+
* JIT emits code to push and pop those registers onto the stack, immediately
75+
* above the callee stack frame.
6676
*/
6777
#define CALLEE_MASK (1 << ARM_R4 | 1 << ARM_R5 | 1 << ARM_R6 | \
6878
1 << ARM_R7 | 1 << ARM_R8 | 1 << ARM_R9 | \
6979
1 << ARM_FP)
7080
#define CALLEE_PUSH_MASK (CALLEE_MASK | 1 << ARM_LR)
7181
#define CALLEE_POP_MASK (CALLEE_MASK | 1 << ARM_PC)
7282

83+
#define CALLER_MASK (1 << ARM_R0 | 1 << ARM_R1 | 1 << ARM_R2 | 1 << ARM_R3)
84+
7385
enum {
7486
/* Stack layout - these are offsets from (top of stack - 4) */
7587
BPF_R2_HI,
@@ -464,6 +476,7 @@ static inline int epilogue_offset(const struct jit_ctx *ctx)
464476

465477
static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op)
466478
{
479+
const int exclude_mask = BIT(ARM_R0) | BIT(ARM_R1);
467480
const s8 *tmp = bpf2a32[TMP_REG_1];
468481

469482
#if __LINUX_ARM_ARCH__ == 7
@@ -495,11 +508,17 @@ static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op)
495508
emit(ARM_MOV_R(ARM_R0, rm), ctx);
496509
}
497510

511+
/* Push caller-saved registers on stack */
512+
emit(ARM_PUSH(CALLER_MASK & ~exclude_mask), ctx);
513+
498514
/* Call appropriate function */
499515
emit_mov_i(ARM_IP, op == BPF_DIV ?
500516
(u32)jit_udiv32 : (u32)jit_mod32, ctx);
501517
emit_blx_r(ARM_IP, ctx);
502518

519+
/* Restore caller-saved registers from stack */
520+
emit(ARM_POP(CALLER_MASK & ~exclude_mask), ctx);
521+
503522
/* Save return value */
504523
if (rd != ARM_R0)
505524
emit(ARM_MOV_R(rd, ARM_R0), ctx);

kernel/bpf/stackmap.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ static inline int stack_map_data_size(struct bpf_map *map)
6363

6464
static int prealloc_elems_and_freelist(struct bpf_stack_map *smap)
6565
{
66-
u32 elem_size = sizeof(struct stack_map_bucket) + smap->map.value_size;
66+
u64 elem_size = sizeof(struct stack_map_bucket) +
67+
(u64)smap->map.value_size;
6768
int err;
6869

6970
smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries,

net/unix/af_unix.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2882,6 +2882,9 @@ static int unix_shutdown(struct socket *sock, int mode)
28822882

28832883
unix_state_lock(sk);
28842884
sk->sk_shutdown |= mode;
2885+
if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) &&
2886+
mode == SHUTDOWN_MASK)
2887+
sk->sk_state = TCP_CLOSE;
28852888
other = unix_peer(sk);
28862889
if (other)
28872890
sock_hold(other);
@@ -2904,12 +2907,10 @@ static int unix_shutdown(struct socket *sock, int mode)
29042907
other->sk_shutdown |= peer_mode;
29052908
unix_state_unlock(other);
29062909
other->sk_state_change(other);
2907-
if (peer_mode == SHUTDOWN_MASK) {
2910+
if (peer_mode == SHUTDOWN_MASK)
29082911
sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP);
2909-
other->sk_state = TCP_CLOSE;
2910-
} else if (peer_mode & RCV_SHUTDOWN) {
2912+
else if (peer_mode & RCV_SHUTDOWN)
29112913
sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN);
2912-
}
29132914
}
29142915
if (other)
29152916
sock_put(other);

samples/bpf/Makefile

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -322,24 +322,23 @@ $(obj)/hbm_edt_kern.o: $(src)/hbm.h $(src)/hbm_kern.h
322322

323323
-include $(BPF_SAMPLES_PATH)/Makefile.target
324324

325-
VMLINUX_BTF_PATHS ?= $(if $(O),$(O)/vmlinux) \
326-
$(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux) \
327-
../../../../vmlinux \
328-
/sys/kernel/btf/vmlinux \
329-
/boot/vmlinux-$(shell uname -r)
325+
VMLINUX_BTF_PATHS ?= $(abspath $(if $(O),$(O)/vmlinux)) \
326+
$(abspath $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux)) \
327+
$(abspath ./vmlinux)
330328
VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS))))
331329

332-
ifeq ($(VMLINUX_BTF),)
333-
$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)")
334-
endif
335-
336330
$(obj)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL)
337331
ifeq ($(VMLINUX_H),)
338332
$(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@
339333
else
340334
$(Q)cp "$(VMLINUX_H)" $@
341335
endif
342336

337+
ifeq ($(VMLINUX_BTF),)
338+
$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)",\
339+
build the kernel or set VMLINUX_BTF variable)
340+
endif
341+
343342
clean-files += vmlinux.h
344343

345344
# Get Clang's default includes on this system, as opposed to those seen by

samples/bpf/bpf_insn.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* SPDX-License-Identifier: GPL-2.0 */
1+
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
22
/* eBPF instruction mini library */
33
#ifndef __BPF_INSN_H
44
#define __BPF_INSN_H

samples/bpf/xdp_redirect_map_multi.bpf.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@
55
#include "xdp_sample.bpf.h"
66
#include "xdp_sample_shared.h"
77

8-
enum {
9-
BPF_F_BROADCAST = (1ULL << 3),
10-
BPF_F_EXCLUDE_INGRESS = (1ULL << 4),
11-
};
12-
138
struct {
149
__uint(type, BPF_MAP_TYPE_DEVMAP_HASH);
1510
__uint(key_size, sizeof(int));

tools/lib/bpf/libbpf.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6894,7 +6894,8 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr)
68946894

68956895
if (obj->gen_loader) {
68966896
/* reset FDs */
6897-
btf__set_fd(obj->btf, -1);
6897+
if (obj->btf)
6898+
btf__set_fd(obj->btf, -1);
68986899
for (i = 0; i < obj->nr_maps; i++)
68996900
obj->maps[i].fd = -1;
69006901
if (!err)

tools/lib/bpf/strset.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ void strset__free(struct strset *set)
8888

8989
hashmap__free(set->strs_hash);
9090
free(set->strs_data);
91+
free(set);
9192
}
9293

9394
size_t strset__data_size(const struct strset *set)

0 commit comments

Comments
 (0)