Add support for intercepting x32 binaries on Linux x64_64.
This commit is contained in:
@@ -55,6 +55,11 @@
|
|||||||
# define __NR_execveat -1
|
# define __NR_execveat -1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* In case userland doesn't define __X32_SYSCALL_BIT. */
|
||||||
|
#if defined(__x86_64__) && !defined(__X32_SYSCALL_BIT)
|
||||||
|
# define __X32_SYSCALL_BIT 0x40000000
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Align address to a word boundary. */
|
/* Align address to a word boundary. */
|
||||||
#define WORDALIGN(_a) (((_a) + (sizeof(long) - 1L)) & ~(sizeof(long) - 1L))
|
#define WORDALIGN(_a) (((_a) + (sizeof(long) - 1L)) & ~(sizeof(long) - 1L))
|
||||||
|
|
||||||
@@ -70,8 +75,10 @@
|
|||||||
* The value of SECCOMP_AUDIT_ARCH is used when matching the architecture
|
* The value of SECCOMP_AUDIT_ARCH is used when matching the architecture
|
||||||
* in the seccomp(2) filter.
|
* in the seccomp(2) filter.
|
||||||
*/
|
*/
|
||||||
#if defined(__amd64__)
|
#if defined(__x86_64__)
|
||||||
# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_X86_64
|
# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_X86_64
|
||||||
|
# define X32_execve __X32_SYSCALL_BIT + 520
|
||||||
|
# define X32_execveat __X32_SYSCALL_BIT + 545
|
||||||
# define user_pt_regs user_regs_struct
|
# define user_pt_regs user_regs_struct
|
||||||
# define reg_syscall(x) (x)->orig_rax
|
# define reg_syscall(x) (x)->orig_rax
|
||||||
# define reg_retval(x) (x)->rax
|
# define reg_retval(x) (x)->rax
|
||||||
@@ -568,10 +575,19 @@ set_exec_filter(void)
|
|||||||
/* Load architecture value (AUDIT_ARCH_*) into the accumulator. */
|
/* Load architecture value (AUDIT_ARCH_*) into the accumulator. */
|
||||||
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, arch)),
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, arch)),
|
||||||
/* Jump to the end unless the architecture matches. */
|
/* Jump to the end unless the architecture matches. */
|
||||||
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SECCOMP_AUDIT_ARCH, 0, 4),
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SECCOMP_AUDIT_ARCH, 0, 6),
|
||||||
/* Load syscall number into the accumulator. */
|
/* Load syscall number into the accumulator. */
|
||||||
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)),
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)),
|
||||||
/* Jump to trace for execve(2)/execveat(2), else allow. */
|
/* Jump to trace for execve(2)/execveat(2), else allow. */
|
||||||
|
#ifdef X32_execve
|
||||||
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, X32_execve, 3, 0),
|
||||||
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, X32_execveat, 2, 0),
|
||||||
|
#else
|
||||||
|
/* No x32 support, check native system call numbers. */
|
||||||
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execve, 3, 0),
|
||||||
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execveat, 2, 3),
|
||||||
|
#endif /* X32_execve */
|
||||||
|
/* If no x32 support, these two instructions are never reached. */
|
||||||
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execve, 1, 0),
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execve, 1, 0),
|
||||||
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execveat, 0, 1),
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execveat, 0, 1),
|
||||||
/* Trace execve(2)/execveat(2) syscalls */
|
/* Trace execve(2)/execveat(2) syscalls */
|
||||||
@@ -671,9 +687,15 @@ ptrace_intercept_execve(pid_t pid, struct intercept_closure *closure)
|
|||||||
/* System call number is stored in the lower 32-bits on 64-bit platforms. */
|
/* System call number is stored in the lower 32-bits on 64-bit platforms. */
|
||||||
syscallno = reg_syscall(®s) & 0xffffffff;
|
syscallno = reg_syscall(®s) & 0xffffffff;
|
||||||
switch (syscallno) {
|
switch (syscallno) {
|
||||||
|
#ifdef X32_execve
|
||||||
|
case X32_execve:
|
||||||
|
#endif
|
||||||
case __NR_execve:
|
case __NR_execve:
|
||||||
/* Handled below. */
|
/* Handled below. */
|
||||||
break;
|
break;
|
||||||
|
#ifdef X32_execveat
|
||||||
|
case X32_execveat:
|
||||||
|
#endif
|
||||||
case __NR_execveat:
|
case __NR_execveat:
|
||||||
/* We don't currently check execveat(2). */
|
/* We don't currently check execveat(2). */
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
|
Reference in New Issue
Block a user