Skip to content

Commit ea1013c

Browse files
committed
Merge tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Pull bpf fixes from Alexei Starovoitov: - Fix BPF builds due to -fms-extensions. selftests (Alexei Starovoitov), bpftool (Quentin Monnet). - Fix build of net/smc when CONFIG_BPF_SYSCALL=y, but CONFIG_BPF_JIT=n (Geert Uytterhoeven) - Fix livepatch/BPF interaction and support reliable unwinding through BPF stack frames (Josh Poimboeuf) - Do not audit capability check in arm64 JIT (Ondrej Mosnacek) - Fix truncated dmabuf BPF iterator reads (T.J. Mercier) - Fix verifier assumptions of bpf_d_path's output buffer (Shuran Liu) - Fix warnings in libbpf when built with -Wdiscarded-qualifiers under C23 (Mikhail Gavrilov) * tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf: selftests/bpf: add regression test for bpf_d_path() bpf: Fix verifier assumptions of bpf_d_path's output buffer selftests/bpf: Add test for truncated dmabuf_iter reads bpf: Fix truncated dmabuf iterator reads x86/unwind/orc: Support reliable unwinding through BPF stack frames bpf: Add bpf_has_frame_pointer() bpf, arm64: Do not audit capability check in do_jit() libbpf: Fix -Wdiscarded-qualifiers under C23 bpftool: Fix build warnings due to MS extensions net: smc: SMC_HS_CTRL_BPF should depend on BPF_JIT selftests/bpf: Add -fms-extensions to bpf build flags
2 parents 64e68f8 + 1d528e7 commit ea1013c

File tree

14 files changed

+256
-48
lines changed

14 files changed

+256
-48
lines changed

arch/arm64/net/bpf_jit_comp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,7 @@ static void __maybe_unused build_bhb_mitigation(struct jit_ctx *ctx)
10041004
arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE)
10051005
return;
10061006

1007-
if (capable(CAP_SYS_ADMIN))
1007+
if (ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN))
10081008
return;
10091009

10101010
if (supports_clearbhb(SCOPE_SYSTEM)) {

arch/x86/kernel/unwind_orc.c

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <linux/objtool.h>
33
#include <linux/module.h>
44
#include <linux/sort.h>
5+
#include <linux/bpf.h>
56
#include <asm/ptrace.h>
67
#include <asm/stacktrace.h>
78
#include <asm/unwind.h>
@@ -172,6 +173,25 @@ static struct orc_entry *orc_ftrace_find(unsigned long ip)
172173
}
173174
#endif
174175

176+
/* Fake frame pointer entry -- used as a fallback for generated code */
177+
static struct orc_entry orc_fp_entry = {
178+
.type = ORC_TYPE_CALL,
179+
.sp_reg = ORC_REG_BP,
180+
.sp_offset = 16,
181+
.bp_reg = ORC_REG_PREV_SP,
182+
.bp_offset = -16,
183+
};
184+
185+
static struct orc_entry *orc_bpf_find(unsigned long ip)
186+
{
187+
#ifdef CONFIG_BPF_JIT
188+
if (bpf_has_frame_pointer(ip))
189+
return &orc_fp_entry;
190+
#endif
191+
192+
return NULL;
193+
}
194+
175195
/*
176196
* If we crash with IP==0, the last successfully executed instruction
177197
* was probably an indirect function call with a NULL function pointer,
@@ -186,15 +206,6 @@ static struct orc_entry null_orc_entry = {
186206
.type = ORC_TYPE_CALL
187207
};
188208

189-
/* Fake frame pointer entry -- used as a fallback for generated code */
190-
static struct orc_entry orc_fp_entry = {
191-
.type = ORC_TYPE_CALL,
192-
.sp_reg = ORC_REG_BP,
193-
.sp_offset = 16,
194-
.bp_reg = ORC_REG_PREV_SP,
195-
.bp_offset = -16,
196-
};
197-
198209
static struct orc_entry *orc_find(unsigned long ip)
199210
{
200211
static struct orc_entry *orc;
@@ -238,6 +249,11 @@ static struct orc_entry *orc_find(unsigned long ip)
238249
if (orc)
239250
return orc;
240251

252+
/* BPF lookup: */
253+
orc = orc_bpf_find(ip);
254+
if (orc)
255+
return orc;
256+
241257
return orc_ftrace_find(ip);
242258
}
243259

@@ -495,9 +511,8 @@ bool unwind_next_frame(struct unwind_state *state)
495511
if (!orc) {
496512
/*
497513
* As a fallback, try to assume this code uses a frame pointer.
498-
* This is useful for generated code, like BPF, which ORC
499-
* doesn't know about. This is just a guess, so the rest of
500-
* the unwind is no longer considered reliable.
514+
* This is just a guess, so the rest of the unwind is no longer
515+
* considered reliable.
501516
*/
502517
orc = &orc_fp_entry;
503518
state->error = true;

arch/x86/net/bpf_jit_comp.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1678,6 +1678,9 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image
16781678
emit_prologue(&prog, image, stack_depth,
16791679
bpf_prog_was_classic(bpf_prog), tail_call_reachable,
16801680
bpf_is_subprog(bpf_prog), bpf_prog->aux->exception_cb);
1681+
1682+
bpf_prog->aux->ksym.fp_start = prog - temp;
1683+
16811684
/* Exception callback will clobber callee regs for its own use, and
16821685
* restore the original callee regs from main prog's stack frame.
16831686
*/
@@ -2736,6 +2739,8 @@ st: if (is_imm8(insn->off))
27362739
pop_r12(&prog);
27372740
}
27382741
EMIT1(0xC9); /* leave */
2742+
bpf_prog->aux->ksym.fp_end = prog - temp;
2743+
27392744
emit_return(&prog, image + addrs[i - 1] + (prog - temp));
27402745
break;
27412746

@@ -3325,6 +3330,9 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
33253330
}
33263331
EMIT1(0x55); /* push rbp */
33273332
EMIT3(0x48, 0x89, 0xE5); /* mov rbp, rsp */
3333+
if (im)
3334+
im->ksym.fp_start = prog - (u8 *)rw_image;
3335+
33283336
if (!is_imm8(stack_size)) {
33293337
/* sub rsp, stack_size */
33303338
EMIT3_off32(0x48, 0x81, 0xEC, stack_size);
@@ -3462,7 +3470,11 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
34623470
emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, -8);
34633471

34643472
emit_ldx(&prog, BPF_DW, BPF_REG_6, BPF_REG_FP, -rbx_off);
3473+
34653474
EMIT1(0xC9); /* leave */
3475+
if (im)
3476+
im->ksym.fp_end = prog - (u8 *)rw_image;
3477+
34663478
if (flags & BPF_TRAMP_F_SKIP_FRAME) {
34673479
/* skip our return address and return to parent */
34683480
EMIT4(0x48, 0x83, 0xC4, 8); /* add rsp, 8 */

include/linux/bpf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,6 +1283,8 @@ struct bpf_ksym {
12831283
struct list_head lnode;
12841284
struct latch_tree_node tnode;
12851285
bool prog;
1286+
u32 fp_start;
1287+
u32 fp_end;
12861288
};
12871289

12881290
enum bpf_tramp_prog_type {
@@ -1511,6 +1513,7 @@ void bpf_image_ksym_add(struct bpf_ksym *ksym);
15111513
void bpf_image_ksym_del(struct bpf_ksym *ksym);
15121514
void bpf_ksym_add(struct bpf_ksym *ksym);
15131515
void bpf_ksym_del(struct bpf_ksym *ksym);
1516+
bool bpf_has_frame_pointer(unsigned long ip);
15141517
int bpf_jit_charge_modmem(u32 size);
15151518
void bpf_jit_uncharge_modmem(u32 size);
15161519
bool bpf_prog_has_trampoline(const struct bpf_prog *prog);

kernel/bpf/core.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,22 @@ struct bpf_prog *bpf_prog_ksym_find(unsigned long addr)
760760
NULL;
761761
}
762762

763+
bool bpf_has_frame_pointer(unsigned long ip)
764+
{
765+
struct bpf_ksym *ksym;
766+
unsigned long offset;
767+
768+
guard(rcu)();
769+
770+
ksym = bpf_ksym_find(ip);
771+
if (!ksym || !ksym->fp_start || !ksym->fp_end)
772+
return false;
773+
774+
offset = ip - ksym->start;
775+
776+
return offset >= ksym->fp_start && offset < ksym->fp_end;
777+
}
778+
763779
const struct exception_table_entry *search_bpf_extables(unsigned long addr)
764780
{
765781
const struct exception_table_entry *e = NULL;

kernel/bpf/dmabuf_iter.c

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,33 @@
66
#include <linux/kernel.h>
77
#include <linux/seq_file.h>
88

9+
struct dmabuf_iter_priv {
10+
/*
11+
* If this pointer is non-NULL, the buffer's refcount is elevated to
12+
* prevent destruction between stop/start. If reading is not resumed and
13+
* start is never called again, then dmabuf_iter_seq_fini drops the
14+
* reference when the iterator is released.
15+
*/
16+
struct dma_buf *dmabuf;
17+
};
18+
919
static void *dmabuf_iter_seq_start(struct seq_file *seq, loff_t *pos)
1020
{
11-
if (*pos)
12-
return NULL;
21+
struct dmabuf_iter_priv *p = seq->private;
22+
23+
if (*pos) {
24+
struct dma_buf *dmabuf = p->dmabuf;
25+
26+
if (!dmabuf)
27+
return NULL;
28+
29+
/*
30+
* Always resume from where we stopped, regardless of the value
31+
* of pos.
32+
*/
33+
p->dmabuf = NULL;
34+
return dmabuf;
35+
}
1336

1437
return dma_buf_iter_begin();
1538
}
@@ -54,8 +77,11 @@ static void dmabuf_iter_seq_stop(struct seq_file *seq, void *v)
5477
{
5578
struct dma_buf *dmabuf = v;
5679

57-
if (dmabuf)
58-
dma_buf_put(dmabuf);
80+
if (dmabuf) {
81+
struct dmabuf_iter_priv *p = seq->private;
82+
83+
p->dmabuf = dmabuf;
84+
}
5985
}
6086

6187
static const struct seq_operations dmabuf_iter_seq_ops = {
@@ -71,11 +97,27 @@ static void bpf_iter_dmabuf_show_fdinfo(const struct bpf_iter_aux_info *aux,
7197
seq_puts(seq, "dmabuf iter\n");
7298
}
7399

100+
static int dmabuf_iter_seq_init(void *priv, struct bpf_iter_aux_info *aux)
101+
{
102+
struct dmabuf_iter_priv *p = (struct dmabuf_iter_priv *)priv;
103+
104+
p->dmabuf = NULL;
105+
return 0;
106+
}
107+
108+
static void dmabuf_iter_seq_fini(void *priv)
109+
{
110+
struct dmabuf_iter_priv *p = (struct dmabuf_iter_priv *)priv;
111+
112+
if (p->dmabuf)
113+
dma_buf_put(p->dmabuf);
114+
}
115+
74116
static const struct bpf_iter_seq_info dmabuf_iter_seq_info = {
75117
.seq_ops = &dmabuf_iter_seq_ops,
76-
.init_seq_private = NULL,
77-
.fini_seq_private = NULL,
78-
.seq_priv_size = 0,
118+
.init_seq_private = dmabuf_iter_seq_init,
119+
.fini_seq_private = dmabuf_iter_seq_fini,
120+
.seq_priv_size = sizeof(struct dmabuf_iter_priv),
79121
};
80122

81123
static struct bpf_iter_reg bpf_dmabuf_reg_info = {

kernel/trace/bpf_trace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,7 @@ static const struct bpf_func_proto bpf_d_path_proto = {
965965
.ret_type = RET_INTEGER,
966966
.arg1_type = ARG_PTR_TO_BTF_ID,
967967
.arg1_btf_id = &bpf_d_path_btf_ids[0],
968-
.arg2_type = ARG_PTR_TO_MEM,
968+
.arg2_type = ARG_PTR_TO_MEM | MEM_WRITE,
969969
.arg3_type = ARG_CONST_SIZE_OR_ZERO,
970970
.allowed = bpf_d_path_allowed,
971971
};

net/smc/Kconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ config SMC_DIAG
2222

2323
config SMC_HS_CTRL_BPF
2424
bool "Generic eBPF hook for SMC handshake flow"
25-
depends on SMC && BPF_SYSCALL
25+
depends on SMC && BPF_JIT && BPF_SYSCALL
2626
default y
2727
help
2828
SMC_HS_CTRL_BPF enables support to register generic eBPF hook for SMC
2929
handshake flow, which offer much greater flexibility in modifying the behavior
3030
of the SMC protocol stack compared to a complete kernel-based approach. Select
31-
this option if you want filtring the handshake process via eBPF programs.
31+
this option if you want filtring the handshake process via eBPF programs.

tools/bpf/bpftool/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ endif
224224

225225
$(OUTPUT)%.bpf.o: skeleton/%.bpf.c $(OUTPUT)vmlinux.h $(LIBBPF_BOOTSTRAP)
226226
$(QUIET_CLANG)$(CLANG) \
227+
-Wno-microsoft-anon-tag \
228+
-fms-extensions \
227229
-I$(or $(OUTPUT),.) \
228230
-I$(srctree)/tools/include/uapi/ \
229231
-I$(LIBBPF_BOOTSTRAP_INCLUDE) \

tools/lib/bpf/libbpf.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8484,7 +8484,7 @@ static int kallsyms_cb(unsigned long long sym_addr, char sym_type,
84848484
struct bpf_object *obj = ctx;
84858485
const struct btf_type *t;
84868486
struct extern_desc *ext;
8487-
char *res;
8487+
const char *res;
84888488

84898489
res = strstr(sym_name, ".llvm.");
84908490
if (sym_type == 'd' && res)
@@ -11818,7 +11818,8 @@ static int avail_kallsyms_cb(unsigned long long sym_addr, char sym_type,
1181811818
*
1181911819
* [0] fb6a421fb615 ("kallsyms: Match symbols exactly with CONFIG_LTO_CLANG")
1182011820
*/
11821-
char sym_trim[256], *psym_trim = sym_trim, *sym_sfx;
11821+
char sym_trim[256], *psym_trim = sym_trim;
11822+
const char *sym_sfx;
1182211823

1182311824
if (!(sym_sfx = strstr(sym_name, ".llvm.")))
1182411825
return 0;
@@ -12401,7 +12402,7 @@ static int resolve_full_path(const char *file, char *result, size_t result_sz)
1240112402
if (!search_paths[i])
1240212403
continue;
1240312404
for (s = search_paths[i]; s != NULL; s = strchr(s, ':')) {
12404-
char *next_path;
12405+
const char *next_path;
1240512406
int seg_len;
1240612407

1240712408
if (s[0] == ':')

0 commit comments

Comments
 (0)