]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
Fix weakness in seccomp-bpf sandbox arg inspection
authorDamien Miller <djm@mindrot.org>
Tue, 14 Mar 2017 01:24:47 +0000 (12:24 +1100)
committerDamien Miller <djm@mindrot.org>
Tue, 14 Mar 2017 01:41:53 +0000 (12:41 +1100)
Syscall arguments are passed via an array of 64-bit values in struct
seccomp_data, but we were only inspecting the bottom 32 bits and not
even those correctly for BE systems.

Fortunately, the only case argument inspection was used was in the
socketcall filtering so using this for sandbox escape seems
impossible.

ok dtucker

sandbox-seccomp-filter.c

index 2e1ed2c52727c38c72eacd4c98064543b83f79df..af5525abb532b2cd32995818176b3f0ce7fb4519 100644 (file)
 # define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP
 #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
 
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define ARG_LO_OFFSET  0
+# define ARG_HI_OFFSET  sizeof(uint32_t)
+#elif __BYTE_ORDER == __BIG_ENDIAN
+# define ARG_LO_OFFSET  sizeof(uint32_t)
+# define ARG_HI_OFFSET  0
+#else
+#error "Unknown endianness"
+#endif
+
 /* Simple helpers to avoid manual errors (but larger BPF programs). */
 #define SC_DENY(_nr, _errno) \
        BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \
        BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \
        BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
 #define SC_ALLOW_ARG(_nr, _arg_nr, _arg_val) \
-       BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 4), \
-       /* load first syscall argument */ \
+       BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 6), \
+       /* load and test first syscall argument, low word */ \
+       BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
+           offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_LO_OFFSET), \
+       BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \
+           ((_arg_val) & 0xFFFFFFFF), 0, 3), \
+       /* load and test first syscall argument, high word */ \
        BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
-           offsetof(struct seccomp_data, args[(_arg_nr)])), \
-       BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_arg_val), 0, 1), \
+           offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_HI_OFFSET), \
+       BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \
+           (((uint32_t)((uint64_t)(_arg_val) >> 32)) & 0xFFFFFFFF), 0, 1), \
        BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), \
        /* reload syscall number; all rules expect it in accumulator */ \
        BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \