]> git.proxmox.com Git - mirror_libseccomp.git/commitdiff
bpf: don't catch the -1 syscall in the x32/x86_64 check
authorPaul Moore <paul@paul-moore.com>
Wed, 15 Feb 2017 20:33:39 +0000 (15:33 -0500)
committerPaul Moore <paul@paul-moore.com>
Thu, 23 Feb 2017 17:17:56 +0000 (12:17 -0500)
The -1 syscall can be used by a tracing process to skip a syscall,
which up until Linux v4.8 was of no concern for libseccomp since the
seccomp filter was only executed at the start of the syscall and not
after the tracing process was notified, however recent kernels also
execute the seccomp filter after the tracing process finishes its
syscall handling; this caused problems on x86_64 systems that didn't
explicitly add an x32 architecture to their filters.

This patch fixes the x32 check to treat the -1 syscall like any other
syscall.

Signed-off-by: Paul Moore <paul@paul-moore.com>
src/gen_bpf.c

index 65e96c43c34fbc2b289740306dd031f9687ce803..54df2ef6129b5080c2a2308850ee2f07fedec232 100644 (file)
@@ -1351,13 +1351,32 @@ static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state,
                        /* filter out x32 */
                        _BPF_INSTR(instr,
                                   _BPF_OP(state->arch, BPF_JMP + BPF_JGE),
-                                  _BPF_JMP_HSH(state->bad_arch_hsh),
+                                  _BPF_JMP_NO,
                                   _BPF_JMP_NO,
                                   _BPF_K(state->arch, X32_SYSCALL_BIT));
                        if (b_head != NULL)
                                instr.jf = _BPF_JMP_HSH(b_head->hash);
                        else
                                instr.jf = _BPF_JMP_HSH(state->def_hsh);
+                       b_new = _blk_append(state, b_new, &instr);
+                       if (b_new == NULL)
+                               goto arch_failure;
+                       /* NOTE: starting with Linux v4.8 the seccomp filters
+                        *       are processed both when the syscall is
+                        *       initially executed as well as after any
+                        *       tracing processes finish so we need to make
+                        *       sure we don't trap the -1 syscall which
+                        *       tracers can use to skip the syscall, see
+                        *       seccomp(2) for more information */
+                       _BPF_INSTR(instr,
+                                  _BPF_OP(state->arch, BPF_JMP + BPF_JEQ),
+                                  _BPF_JMP_NO,
+                                  _BPF_JMP_HSH(state->bad_arch_hsh),
+                                  _BPF_K(state->arch, -1));
+                       if (b_head != NULL)
+                               instr.jt = _BPF_JMP_HSH(b_head->hash);
+                       else
+                               instr.jt = _BPF_JMP_HSH(state->def_hsh);
                        blk_cnt++;
                } else if (state->arch->token == SCMP_ARCH_X32) {
                        /* filter out x86_64 */