![Tycho Andersen](/assets/img/avatar_default.png)
This patch adds support for dumping a process' (classic BPF) seccomp filters via ptrace. PTRACE_SECCOMP_GET_FILTER allows the tracer to dump the user's classic BPF seccomp filters. addr should be an integer which represents the ith seccomp filter (0 is the most recently installed filter). data should be a struct sock_filter * with enough room for the ith filter, or NULL, in which case the filter is not saved. The return value for this command is the number of BPF instructions the program represents, or negative in the case of errors. Command specific errors are ENOENT: which indicates that there is no ith filter in this seccomp tree, and EMEDIUMTYPE, which indicates that the ith filter was not installed as a classic BPF filter. A caveat with this approach is that there is no way to get explicitly at the heirarchy of seccomp filters, and users need to memcmp() filters to decide which are inherited. This means that a task which installs two of the same filter can potentially confuse users of this interface. v2: * make save_orig const * check that the orig_prog exists (not necessary right now, but when grows eBPF support it will be) * s/n/filter_off and make it an unsigned long to match ptrace * count "down" the tree instead of "up" when passing a filter offset v3: * don't take the current task's lock for inspecting its seccomp mode * use a 0x42** constant for the ptrace command value v4: * don't copy to userspace while holding spinlocks v5: * add another condition to WARN_ON v6: * rebase on net-next Signed-off-by: Tycho Andersen <tycho.andersen@canonical.com> Acked-by: Kees Cook <keescook@chromium.org> CC: Will Drewry <wad@chromium.org> Reviewed-by: Oleg Nesterov <oleg@redhat.com> CC: Andy Lutomirski <luto@amacapital.net> CC: Pavel Emelyanov <xemul@parallels.com> CC: Serge E. Hallyn <serge.hallyn@ubuntu.com> CC: Alexei Starovoitov <ast@kernel.org> CC: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
104 lines
3.2 KiB
C
104 lines
3.2 KiB
C
#ifndef _UAPI_LINUX_PTRACE_H
|
|
#define _UAPI_LINUX_PTRACE_H
|
|
/* ptrace.h */
|
|
/* structs and defines to help the user use the ptrace system call. */
|
|
|
|
/* has the defines to get at the registers. */
|
|
|
|
#include <linux/types.h>
|
|
|
|
#define PTRACE_TRACEME 0
|
|
#define PTRACE_PEEKTEXT 1
|
|
#define PTRACE_PEEKDATA 2
|
|
#define PTRACE_PEEKUSR 3
|
|
#define PTRACE_POKETEXT 4
|
|
#define PTRACE_POKEDATA 5
|
|
#define PTRACE_POKEUSR 6
|
|
#define PTRACE_CONT 7
|
|
#define PTRACE_KILL 8
|
|
#define PTRACE_SINGLESTEP 9
|
|
|
|
#define PTRACE_ATTACH 16
|
|
#define PTRACE_DETACH 17
|
|
|
|
#define PTRACE_SYSCALL 24
|
|
|
|
/* 0x4200-0x4300 are reserved for architecture-independent additions. */
|
|
#define PTRACE_SETOPTIONS 0x4200
|
|
#define PTRACE_GETEVENTMSG 0x4201
|
|
#define PTRACE_GETSIGINFO 0x4202
|
|
#define PTRACE_SETSIGINFO 0x4203
|
|
|
|
/*
|
|
* Generic ptrace interface that exports the architecture specific regsets
|
|
* using the corresponding NT_* types (which are also used in the core dump).
|
|
* Please note that the NT_PRSTATUS note type in a core dump contains a full
|
|
* 'struct elf_prstatus'. But the user_regset for NT_PRSTATUS contains just the
|
|
* elf_gregset_t that is the pr_reg field of 'struct elf_prstatus'. For all the
|
|
* other user_regset flavors, the user_regset layout and the ELF core dump note
|
|
* payload are exactly the same layout.
|
|
*
|
|
* This interface usage is as follows:
|
|
* struct iovec iov = { buf, len};
|
|
*
|
|
* ret = ptrace(PTRACE_GETREGSET/PTRACE_SETREGSET, pid, NT_XXX_TYPE, &iov);
|
|
*
|
|
* On the successful completion, iov.len will be updated by the kernel,
|
|
* specifying how much the kernel has written/read to/from the user's iov.buf.
|
|
*/
|
|
#define PTRACE_GETREGSET 0x4204
|
|
#define PTRACE_SETREGSET 0x4205
|
|
|
|
#define PTRACE_SEIZE 0x4206
|
|
#define PTRACE_INTERRUPT 0x4207
|
|
#define PTRACE_LISTEN 0x4208
|
|
|
|
#define PTRACE_PEEKSIGINFO 0x4209
|
|
|
|
struct ptrace_peeksiginfo_args {
|
|
__u64 off; /* from which siginfo to start */
|
|
__u32 flags;
|
|
__s32 nr; /* how may siginfos to take */
|
|
};
|
|
|
|
#define PTRACE_GETSIGMASK 0x420a
|
|
#define PTRACE_SETSIGMASK 0x420b
|
|
|
|
#define PTRACE_SECCOMP_GET_FILTER 0x420c
|
|
|
|
/* Read signals from a shared (process wide) queue */
|
|
#define PTRACE_PEEKSIGINFO_SHARED (1 << 0)
|
|
|
|
/* Wait extended result codes for the above trace options. */
|
|
#define PTRACE_EVENT_FORK 1
|
|
#define PTRACE_EVENT_VFORK 2
|
|
#define PTRACE_EVENT_CLONE 3
|
|
#define PTRACE_EVENT_EXEC 4
|
|
#define PTRACE_EVENT_VFORK_DONE 5
|
|
#define PTRACE_EVENT_EXIT 6
|
|
#define PTRACE_EVENT_SECCOMP 7
|
|
/* Extended result codes which enabled by means other than options. */
|
|
#define PTRACE_EVENT_STOP 128
|
|
|
|
/* Options set using PTRACE_SETOPTIONS or using PTRACE_SEIZE @data param */
|
|
#define PTRACE_O_TRACESYSGOOD 1
|
|
#define PTRACE_O_TRACEFORK (1 << PTRACE_EVENT_FORK)
|
|
#define PTRACE_O_TRACEVFORK (1 << PTRACE_EVENT_VFORK)
|
|
#define PTRACE_O_TRACECLONE (1 << PTRACE_EVENT_CLONE)
|
|
#define PTRACE_O_TRACEEXEC (1 << PTRACE_EVENT_EXEC)
|
|
#define PTRACE_O_TRACEVFORKDONE (1 << PTRACE_EVENT_VFORK_DONE)
|
|
#define PTRACE_O_TRACEEXIT (1 << PTRACE_EVENT_EXIT)
|
|
#define PTRACE_O_TRACESECCOMP (1 << PTRACE_EVENT_SECCOMP)
|
|
|
|
/* eventless options */
|
|
#define PTRACE_O_EXITKILL (1 << 20)
|
|
#define PTRACE_O_SUSPEND_SECCOMP (1 << 21)
|
|
|
|
#define PTRACE_O_MASK (\
|
|
0x000000ff | PTRACE_O_EXITKILL | PTRACE_O_SUSPEND_SECCOMP)
|
|
|
|
#include <asm/ptrace.h>
|
|
|
|
|
|
#endif /* _UAPI_LINUX_PTRACE_H */
|