bjm.c \
block.c \
bpf.c \
+ bpf_filter.c \
+ bpf_filter.h \
+ bpf_fprog.h \
+ bpf_seccomp_filter.c \
btrfs.c \
cacheflush.c \
capability.c \
fanotify.c \
fchownat.c \
fcntl.c \
- fetch_seccomp_fprog.c \
+ fetch_bpf_fprog.c \
fetch_struct_flock.c \
fetch_struct_mmsghdr.c \
fetch_struct_msghdr.c \
fetch_struct_statfs.c \
file_handle.c \
file_ioctl.c \
- fs_x_ioctl.c \
flock.c \
flock.h \
+ fs_x_ioctl.c \
futex.c \
gcc_compat.h \
get_robust_list.c \
sched_attr.h \
scsi.c \
seccomp.c \
- seccomp_fprog.h \
sendfile.c \
sg_io_v3.c \
sg_io_v4.c \
--- /dev/null
+/*
+ * Decoder of classic BPF programs.
+ *
+ * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "defs.h"
+
+#include "bpf_filter.h"
+#include "bpf_fprog.h"
+
+#include <linux/filter.h>
+#include "xlat/bpf_class.h"
+#include "xlat/bpf_miscop.h"
+#include "xlat/bpf_mode.h"
+#include "xlat/bpf_op_alu.h"
+#include "xlat/bpf_op_jmp.h"
+#include "xlat/bpf_rval.h"
+#include "xlat/bpf_size.h"
+#include "xlat/bpf_src.h"
+
+static void
+print_bpf_filter_code(const uint16_t code)
+{
+ uint16_t i = code & ~BPF_CLASS(code);
+
+ printxval(bpf_class, BPF_CLASS(code), "BPF_???");
+ switch (BPF_CLASS(code)) {
+ case BPF_LD:
+ case BPF_LDX:
+ tprints("|");
+ printxval(bpf_size, BPF_SIZE(code), "BPF_???");
+ tprints("|");
+ printxval(bpf_mode, BPF_MODE(code), "BPF_???");
+ break;
+ case BPF_ST:
+ case BPF_STX:
+ if (i) {
+ tprintf("|%#x", i);
+ tprints_comment("BPF_???");
+ }
+ break;
+ case BPF_ALU:
+ tprints("|");
+ printxval(bpf_src, BPF_SRC(code), "BPF_???");
+ tprints("|");
+ printxval(bpf_op_alu, BPF_OP(code), "BPF_???");
+ break;
+ case BPF_JMP:
+ tprints("|");
+ printxval(bpf_src, BPF_SRC(code), "BPF_???");
+ tprints("|");
+ printxval(bpf_op_jmp, BPF_OP(code), "BPF_???");
+ break;
+ case BPF_RET:
+ tprints("|");
+ printxval(bpf_rval, BPF_RVAL(code), "BPF_???");
+ i &= ~BPF_RVAL(code);
+ if (i) {
+ tprintf("|%#x", i);
+ tprints_comment("BPF_???");
+ }
+ break;
+ case BPF_MISC:
+ tprints("|");
+ printxval(bpf_miscop, BPF_MISCOP(code), "BPF_???");
+ i &= ~BPF_MISCOP(code);
+ if (i) {
+ tprintf("|%#x", i);
+ tprints_comment("BPF_???");
+ }
+ break;
+ }
+}
+
+static void
+print_bpf_filter_stmt(const struct bpf_filter_block *const filter,
+ const print_bpf_filter_fn print_k)
+{
+ tprints("BPF_STMT(");
+ print_bpf_filter_code(filter->code);
+ tprints(", ");
+ if (!print_k || !print_k(filter))
+ tprintf("%#x", filter->k);
+ tprints(")");
+}
+
+static void
+print_bpf_filter_jump(const struct bpf_filter_block *const filter)
+{
+ tprints("BPF_JUMP(");
+ print_bpf_filter_code(filter->code);
+ tprintf(", %#x, %#x, %#x)", filter->k, filter->jt, filter->jf);
+}
+
+struct bpf_filter_block_data {
+ const print_bpf_filter_fn fn;
+ unsigned int count;
+};
+
+static bool
+print_bpf_filter_block(struct tcb *const tcp, void *const elem_buf,
+ const size_t elem_size, void *const data)
+{
+ const struct bpf_filter_block *const filter = elem_buf;
+ struct bpf_filter_block_data *const fbd = data;
+
+ if (fbd->count++ >= BPF_MAXINSNS) {
+ tprints("...");
+ return false;
+ }
+
+ if (filter->jt || filter->jf)
+ print_bpf_filter_jump(filter);
+ else
+ print_bpf_filter_stmt(filter, fbd->fn);
+
+ return true;
+}
+
+void
+print_bpf_fprog(struct tcb *const tcp, const kernel_ulong_t addr,
+ const unsigned short len, const print_bpf_filter_fn print_k)
+{
+ if (abbrev(tcp)) {
+ printaddr(addr);
+ } else {
+ struct bpf_filter_block_data fbd = { .fn = print_k };
+ struct bpf_filter_block filter;
+
+ print_array(tcp, addr, len, &filter, sizeof(filter),
+ umoven_or_printaddr, print_bpf_filter_block, &fbd);
+ }
+}
+
+void
+decode_bpf_fprog(struct tcb *const tcp, const kernel_ulong_t addr,
+ const print_bpf_filter_fn print_k)
+{
+ struct bpf_fprog fprog;
+
+ if (fetch_bpf_fprog(tcp, addr, &fprog)) {
+ tprintf("{len=%hu, filter=", fprog.len);
+ print_bpf_fprog(tcp, fprog.filter, fprog.len, print_k);
+ tprints("}");
+ }
+}
--- /dev/null
+/*
+ * Classic BPF filter block.
+ *
+ * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef STRACE_BPF_FILTER_H
+#define STRACE_BPF_FILTER_H
+
+struct bpf_filter_block {
+ uint16_t code;
+ uint8_t jt;
+ uint8_t jf;
+ uint32_t k;
+};
+
+typedef bool (*print_bpf_filter_fn)(const struct bpf_filter_block *);
+
+extern void
+print_bpf_fprog(struct tcb *const tcp, const kernel_ulong_t addr,
+ const unsigned short len, const print_bpf_filter_fn print_k);
+
+extern void
+decode_bpf_fprog(struct tcb *const tcp, const kernel_ulong_t addr,
+ const print_bpf_filter_fn print_k);
+
+#endif /* !STRACE_BPF_FILTER_H */
--- /dev/null
+#ifndef STRACE_BPF_FPROG_H
+#define STRACE_BPF_FPROG_H
+
+struct bpf_fprog {
+ unsigned short len;
+ kernel_ulong_t filter;
+};
+
+#endif /* !STRACE_BPF_FPROG_H */
--- /dev/null
+/*
+ * Decoder of seccomp filter programs.
+ *
+ * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "defs.h"
+
+#include "bpf_filter.h"
+
+#include <linux/filter.h>
+#ifdef HAVE_LINUX_SECCOMP_H
+# include <linux/seccomp.h>
+#endif
+#ifndef SECCOMP_RET_ACTION
+# define SECCOMP_RET_ACTION 0x7fff0000U
+#endif
+#include "xlat/seccomp_ret_action.h"
+
+static bool
+print_seccomp_filter_k(const struct bpf_filter_block *const fp)
+{
+ if (BPF_CLASS(fp->code) == BPF_RET) {
+ unsigned int action = SECCOMP_RET_ACTION & fp->k;
+ unsigned int data = fp->k & ~action;
+
+ printxval(seccomp_ret_action, action, "SECCOMP_RET_???");
+ if (data)
+ tprintf("|%#x", data);
+
+ return true;
+ }
+
+ return false;
+}
+
+void
+print_seccomp_fprog(struct tcb *const tcp, const kernel_ulong_t addr,
+ const unsigned short len)
+{
+ print_bpf_fprog(tcp, addr, len, print_seccomp_filter_k);
+}
+
+void
+decode_seccomp_fprog(struct tcb *const tcp, const kernel_ulong_t addr)
+{
+ decode_bpf_fprog(tcp, addr, print_seccomp_filter_k);
+}
extern const char *sprint_open_modes(unsigned int);
extern void
-print_seccomp_filter(struct tcb *, kernel_ulong_t addr);
+decode_seccomp_fprog(struct tcb *, kernel_ulong_t addr);
extern void
print_seccomp_fprog(struct tcb *, kernel_ulong_t addr, unsigned short len);
/*
- * Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
- * Copyright (c) 2015-2017 The strace developers.
+ * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include "defs.h"
-#include DEF_MPERS_TYPE(seccomp_fprog_t)
+#include DEF_MPERS_TYPE(struct_sock_fprog)
-#include "seccomp_fprog.h"
-typedef struct seccomp_fprog seccomp_fprog_t;
+#include <linux/filter.h>
+typedef struct sock_fprog struct_sock_fprog;
#include MPERS_DEFS
+#include "bpf_fprog.h"
-MPERS_PRINTER_DECL(bool, fetch_seccomp_fprog, struct tcb *const tcp,
+MPERS_PRINTER_DECL(bool, fetch_bpf_fprog, struct tcb *const tcp,
const kernel_ulong_t addr, void *const p)
{
- struct seccomp_fprog *pfp = p;
- seccomp_fprog_t mfp;
+ struct bpf_fprog *pfp = p;
+ struct_sock_fprog mfp;
- if (sizeof(*pfp) == sizeof(mfp))
+ if ((sizeof(*pfp) == sizeof(mfp))
+ && (offsetof(struct bpf_fprog, filter) ==
+ offsetof(struct_sock_fprog, filter)))
return !umove_or_printaddr(tcp, addr, pfp);
if (umove_or_printaddr(tcp, addr, &mfp))
return false;
pfp->len = mfp.len;
- pfp->filter = mfp.filter;
+ pfp->filter =
+#ifndef IN_MPERS
+ (uintptr_t)
+#endif
+ mfp.filter;
return true;
}
return RVAL_DECODED;
if (SECCOMP_MODE_FILTER == arg2) {
tprints(", ");
- print_seccomp_filter(tcp, arg3);
+ decode_seccomp_fprog(tcp, arg3);
return RVAL_DECODED;
}
print_prctl_args(tcp, 2);
/*
- * Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
- * Copyright (c) 2015-2017 The strace developers.
+ * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include "xlat/seccomp_ops.h"
#include "xlat/seccomp_filter_flags.h"
-#include <linux/filter.h>
-#include "xlat/bpf_class.h"
-#include "xlat/bpf_miscop.h"
-#include "xlat/bpf_mode.h"
-#include "xlat/bpf_op_alu.h"
-#include "xlat/bpf_op_jmp.h"
-#include "xlat/bpf_rval.h"
-#include "xlat/bpf_size.h"
-#include "xlat/bpf_src.h"
-
-#ifndef SECCOMP_RET_ACTION
-# define SECCOMP_RET_ACTION 0x7fff0000U
-#endif
-#include "xlat/seccomp_ret_action.h"
-
-struct bpf_filter {
- uint16_t code;
- uint8_t jt;
- uint8_t jf;
- uint32_t k;
-};
-
-static void
-decode_bpf_code(uint16_t code)
-{
- uint16_t i = code & ~BPF_CLASS(code);
-
- printxval(bpf_class, BPF_CLASS(code), "BPF_???");
- switch (BPF_CLASS(code)) {
- case BPF_LD:
- case BPF_LDX:
- tprints("|");
- printxval(bpf_size, BPF_SIZE(code), "BPF_???");
- tprints("|");
- printxval(bpf_mode, BPF_MODE(code), "BPF_???");
- break;
- case BPF_ST:
- case BPF_STX:
- if (i) {
- tprintf("|%#x", i);
- tprints_comment("BPF_???");
- }
- break;
- case BPF_ALU:
- tprints("|");
- printxval(bpf_src, BPF_SRC(code), "BPF_???");
- tprints("|");
- printxval(bpf_op_alu, BPF_OP(code), "BPF_???");
- break;
- case BPF_JMP:
- tprints("|");
- printxval(bpf_src, BPF_SRC(code), "BPF_???");
- tprints("|");
- printxval(bpf_op_jmp, BPF_OP(code), "BPF_???");
- break;
- case BPF_RET:
- tprints("|");
- printxval(bpf_rval, BPF_RVAL(code), "BPF_???");
- i &= ~BPF_RVAL(code);
- if (i) {
- tprintf("|%#x", i);
- tprints_comment("BPF_???");
- }
- break;
- case BPF_MISC:
- tprints("|");
- printxval(bpf_miscop, BPF_MISCOP(code), "BPF_???");
- i &= ~BPF_MISCOP(code);
- if (i) {
- tprintf("|%#x", i);
- tprints_comment("BPF_???");
- }
- break;
- }
-
-}
-
-static void
-decode_bpf_stmt(const struct bpf_filter *filter)
-{
- tprints("BPF_STMT(");
- decode_bpf_code(filter->code);
- tprints(", ");
- if (BPF_CLASS(filter->code) == BPF_RET) {
- unsigned int action = SECCOMP_RET_ACTION & filter->k;
- unsigned int data = filter->k & ~action;
-
- printxval(seccomp_ret_action, action, "SECCOMP_RET_???");
- if (data)
- tprintf("|%#x)", data);
- else
- tprints(")");
- } else {
- tprintf("%#x)", filter->k);
- }
-}
-
-static void
-decode_bpf_jump(const struct bpf_filter *filter)
-{
- tprints("BPF_JUMP(");
- decode_bpf_code(filter->code);
- tprintf(", %#x, %#x, %#x)",
- filter->k, filter->jt, filter->jf);
-}
-
-static bool
-print_bpf_filter(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
-{
- const struct bpf_filter *filter = elem_buf;
- unsigned int *pn = data;
-
- if ((*pn)++ >= BPF_MAXINSNS) {
- tprints("...");
- return false;
- }
-
- if (filter->jt || filter->jf)
- decode_bpf_jump(filter);
- else
- decode_bpf_stmt(filter);
-
- return true;
-}
-
-void
-print_seccomp_fprog(struct tcb *const tcp, const kernel_ulong_t addr,
- const unsigned short len)
-{
- if (abbrev(tcp)) {
- printaddr(addr);
- } else {
- unsigned int insns = 0;
- struct bpf_filter filter;
-
- print_array(tcp, addr, len, &filter, sizeof(filter),
- umoven_or_printaddr, print_bpf_filter, &insns);
- }
-}
-
-#include "seccomp_fprog.h"
-
-void
-print_seccomp_filter(struct tcb *const tcp, const kernel_ulong_t addr)
-{
- struct seccomp_fprog fprog;
-
- if (fetch_seccomp_fprog(tcp, addr, &fprog)) {
- tprintf("{len=%hu, filter=", fprog.len);
- print_seccomp_fprog(tcp, fprog.filter, fprog.len);
- tprints("}");
- }
-}
-
static void
decode_seccomp_set_mode_strict(const unsigned int flags,
const kernel_ulong_t addr)
printflags(seccomp_filter_flags, tcp->u_arg[1],
"SECCOMP_FILTER_FLAG_???");
tprints(", ");
- print_seccomp_filter(tcp, tcp->u_arg[2]);
+ decode_seccomp_fprog(tcp, tcp->u_arg[2]);
} else {
decode_seccomp_set_mode_strict(tcp->u_arg[1],
tcp->u_arg[2]);
+++ /dev/null
-#ifndef STRACE_SECCOMP_FPROG_H
-#define STRACE_SECCOMP_FPROG_H
-
-struct seccomp_fprog {
- unsigned short len;
- unsigned long filter;
-};
-
-#endif /* !STRACE_SECCOMP_FPROG_H */