Skip to content

Commit 9a3d1eb

Browse files
committed
Merge branch 'libbpf: Fix accessing syscall arguments'
Ilya Leoshkevich says: ==================== libbpf now has macros to access syscall arguments in an architecture-agnostic manner, but unfortunately they have a number of issues on non-Intel arches, which this series aims to fix. v1: https://lore.kernel.org/bpf/20220201234200.1836443-1-iii@linux.ibm.com/ v1 -> v2: * Put orig_gpr2 in place of args[1] on s390 (Vasily). * Fix arm64, powerpc and riscv (Heiko). v2: https://lore.kernel.org/bpf/20220204041955.1958263-1-iii@linux.ibm.com/ v2 -> v3: * Undo args[1] change (Andrii). * Rename PT_REGS_SYSCALL to PT_REGS_SYSCALL_REGS (Andrii). * Split the riscv patch (Andrii). +cc Naveen. ==================== Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
2 parents 0908a66 + 088d6aa commit 9a3d1eb

File tree

6 files changed

+31
-5
lines changed

6 files changed

+31
-5
lines changed

arch/arm64/include/asm/ptrace.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,9 @@ struct pt_regs {
183183
u64 sp;
184184
u64 pc;
185185
u64 pstate;
186+
u64 orig_x0;
186187
};
187188
};
188-
u64 orig_x0;
189189
#ifdef __AARCH64EB__
190190
u32 unused2;
191191
s32 syscallno;

arch/arm64/include/uapi/asm/ptrace.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ struct user_pt_regs {
9090
__u64 sp;
9191
__u64 pc;
9292
__u64 pstate;
93+
__u64 orig_x0;
9394
};
9495

9596
struct user_fpsimd_state {

arch/s390/include/asm/ptrace.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ struct pt_regs {
8383
unsigned long args[1];
8484
psw_t psw;
8585
unsigned long gprs[NUM_GPRS];
86+
unsigned long orig_gpr2;
8687
};
8788
};
88-
unsigned long orig_gpr2;
8989
union {
9090
struct {
9191
unsigned int int_code;

arch/s390/include/uapi/asm/ptrace.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ typedef struct {
295295
unsigned long args[1];
296296
psw_t psw;
297297
unsigned long gprs[NUM_GPRS];
298+
unsigned long orig_gpr2;
298299
} user_pt_regs;
299300

300301
/*

tools/lib/bpf/bpf_tracing.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@
117117
/* s390 provides user_pt_regs instead of struct pt_regs to userspace */
118118
#define __PT_REGS_CAST(x) ((const user_pt_regs *)(x))
119119
#define __PT_PARM1_REG gprs[2]
120+
#define __PT_PARM1_REG_SYSCALL orig_gpr2
120121
#define __PT_PARM2_REG gprs[3]
121122
#define __PT_PARM3_REG gprs[4]
122123
#define __PT_PARM4_REG gprs[5]
@@ -145,6 +146,7 @@
145146
/* arm64 provides struct user_pt_regs instead of struct pt_regs to userspace */
146147
#define __PT_REGS_CAST(x) ((const struct user_pt_regs *)(x))
147148
#define __PT_PARM1_REG regs[0]
149+
#define __PT_PARM1_REG_SYSCALL orig_x0
148150
#define __PT_PARM2_REG regs[1]
149151
#define __PT_PARM3_REG regs[2]
150152
#define __PT_PARM4_REG regs[3]
@@ -180,6 +182,7 @@
180182
#define __PT_RC_REG gpr[3]
181183
#define __PT_SP_REG sp
182184
#define __PT_IP_REG nip
185+
#define PT_REGS_SYSCALL_REGS(ctx) ctx
183186

184187
#elif defined(bpf_target_sparc)
185188

@@ -211,7 +214,8 @@
211214
#define __PT_FP_REG fp
212215
#define __PT_RC_REG a5
213216
#define __PT_SP_REG sp
214-
#define __PT_IP_REG epc
217+
#define __PT_IP_REG pc
218+
#define PT_REGS_SYSCALL_REGS(ctx) ctx
215219

216220
#endif
217221

@@ -265,7 +269,11 @@ struct pt_regs;
265269

266270
#endif
267271

272+
#ifdef __PT_PARM1_REG_SYSCALL
273+
#define PT_REGS_PARM1_SYSCALL(x) (__PT_REGS_CAST(x)->__PT_PARM1_REG_SYSCALL)
274+
#else /* __PT_PARM1_REG_SYSCALL */
268275
#define PT_REGS_PARM1_SYSCALL(x) PT_REGS_PARM1(x)
276+
#endif
269277
#define PT_REGS_PARM2_SYSCALL(x) PT_REGS_PARM2(x)
270278
#define PT_REGS_PARM3_SYSCALL(x) PT_REGS_PARM3(x)
271279
#ifdef __PT_PARM4_REG_SYSCALL
@@ -275,7 +283,11 @@ struct pt_regs;
275283
#endif
276284
#define PT_REGS_PARM5_SYSCALL(x) PT_REGS_PARM5(x)
277285

286+
#ifdef __PT_PARM1_REG_SYSCALL
287+
#define PT_REGS_PARM1_CORE_SYSCALL(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM1_REG_SYSCALL)
288+
#else /* __PT_PARM1_REG_SYSCALL */
278289
#define PT_REGS_PARM1_CORE_SYSCALL(x) PT_REGS_PARM1_CORE(x)
290+
#endif
279291
#define PT_REGS_PARM2_CORE_SYSCALL(x) PT_REGS_PARM2_CORE(x)
280292
#define PT_REGS_PARM3_CORE_SYSCALL(x) PT_REGS_PARM3_CORE(x)
281293
#ifdef __PT_PARM4_REG_SYSCALL
@@ -326,6 +338,15 @@ struct pt_regs;
326338

327339
#endif /* defined(bpf_target_defined) */
328340

341+
/*
342+
* When invoked from a syscall handler kprobe, returns a pointer to a
343+
* struct pt_regs containing syscall arguments and suitable for passing to
344+
* PT_REGS_PARMn_SYSCALL() and PT_REGS_PARMn_CORE_SYSCALL().
345+
*/
346+
#ifndef PT_REGS_SYSCALL_REGS
347+
#define PT_REGS_SYSCALL_REGS(ctx) ((struct pt_regs *)PT_REGS_PARM1(ctx))
348+
#endif
349+
329350
#ifndef ___bpf_concat
330351
#define ___bpf_concat(a, b) a ## b
331352
#endif

tools/testing/selftests/bpf/progs/bpf_syscall_macro.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,17 @@ int BPF_KPROBE(handle_sys_prctl)
2828
{
2929
struct pt_regs *real_regs;
3030
pid_t pid = bpf_get_current_pid_tgid() >> 32;
31+
unsigned long tmp;
3132

3233
if (pid != filter_pid)
3334
return 0;
3435

35-
real_regs = (struct pt_regs *)PT_REGS_PARM1(ctx);
36+
real_regs = PT_REGS_SYSCALL_REGS(ctx);
3637

3738
/* test for PT_REGS_PARM */
38-
bpf_probe_read_kernel(&arg1, sizeof(arg1), &PT_REGS_PARM1_SYSCALL(real_regs));
39+
40+
bpf_probe_read_kernel(&tmp, sizeof(tmp), &PT_REGS_PARM1_SYSCALL(real_regs));
41+
arg1 = tmp;
3942
bpf_probe_read_kernel(&arg2, sizeof(arg2), &PT_REGS_PARM2_SYSCALL(real_regs));
4043
bpf_probe_read_kernel(&arg3, sizeof(arg3), &PT_REGS_PARM3_SYSCALL(real_regs));
4144
bpf_probe_read_kernel(&arg4_cx, sizeof(arg4_cx), &PT_REGS_PARM4(real_regs));

0 commit comments

Comments
 (0)