filesystem-disk-old-kernel-test.c++ (4834B)
1 // Copyright (c) 2016 Sandstorm Development Group, Inc. and contributors 2 // Licensed under the MIT License: 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a copy 5 // of this software and associated documentation files (the "Software"), to deal 6 // in the Software without restriction, including without limitation the rights 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 // copies of the Software, and to permit persons to whom the Software is 9 // furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 // THE SOFTWARE. 21 22 #if __linux__ && __x86_64__ && defined(__has_include) 23 #if __has_include(<linux/seccomp.h>) && \ 24 __has_include(<linux/filter.h>) && \ 25 __has_include(<linux/audit.h>) && \ 26 __has_include(<linux/signal.h>) && \ 27 __has_include(<sys/ptrace.h>) 28 // This test re-runs filesystem-disk-test.c++ with newfangled Linux kernel features disabled. 29 // 30 // This test must be compiled as a separate program, since it alters the calling process by 31 // enabling seccomp to disable the kernel features. 32 // 33 // At present this test only runs under Ekam builds. It *could* reasonably easily be added to the 34 // autotools or cmake builds, but would require compiling a separate test binary, which is a bit 35 // weird, and may lead to spurious error reports on systems that don't support seccomp for whatever 36 // reason. 37 38 #include <syscall.h> 39 #include <unistd.h> 40 #include <sys/prctl.h> 41 #include <sys/ptrace.h> 42 #include <linux/seccomp.h> 43 #include <linux/filter.h> 44 #include <kj/debug.h> 45 46 #ifdef SECCOMP_SET_MODE_FILTER 47 48 namespace { 49 50 #if 0 51 // Source code of the seccomp filter: 52 53 ld [0] /* offsetof(struct seccomp_data, nr) */ 54 jeq #8, lseek /* __NR_lseek */ 55 jeq #16, inval /* __NR_ioctl */ 56 jeq #40, nosys /* __NR_sendfile */ 57 jeq #257, openat /* __NR_openat */ 58 jeq #285, notsup /* __NR_fallocate */ 59 jeq #316, nosys /* __NR_renameat2 */ 60 jmp good 61 62 openat: 63 ld [32] /* offsetof(struct seccomp_data, args[2]), aka flags */ 64 and #4259840 /* O_TMPFILE */ 65 jeq #4259840, notsup 66 jmp good 67 68 lseek: 69 ld [32] /* offsetof(struct seccomp_data, args[2]), aka whence */ 70 jeq #3, inval /* SEEK_DATA */ 71 jeq #4, inval /* SEEK_HOLE */ 72 jmp good 73 74 inval: ret #0x00050016 /* SECCOMP_RET_ERRNO | EINVAL */ 75 nosys: ret #0x00050026 /* SECCOMP_RET_ERRNO | ENOSYS */ 76 notsup: ret #0x0005005f /* SECCOMP_RET_ERRNO | EOPNOTSUPP */ 77 good: ret #0x7fff0000 /* SECCOMP_RET_ALLOW */ 78 79 #endif 80 81 struct SetupSeccompForFilesystemTest { 82 SetupSeccompForFilesystemTest() { 83 struct sock_filter filter[] { 84 { 0x20, 0, 0, 0000000000 }, 85 { 0x15, 10, 0, 0x00000008 }, 86 { 0x15, 13, 0, 0x00000010 }, 87 { 0x15, 13, 0, 0x00000028 }, 88 { 0x15, 3, 0, 0x00000101 }, 89 { 0x15, 12, 0, 0x0000011d }, 90 { 0x15, 10, 0, 0x0000013c }, 91 { 0x05, 0, 0, 0x0000000b }, 92 { 0x20, 0, 0, 0x00000020 }, 93 { 0x54, 0, 0, 0x00410000 }, 94 { 0x15, 7, 0, 0x00410000 }, 95 { 0x05, 0, 0, 0x00000007 }, 96 { 0x20, 0, 0, 0x00000020 }, 97 { 0x15, 2, 0, 0x00000003 }, 98 { 0x15, 1, 0, 0x00000004 }, 99 { 0x05, 0, 0, 0x00000003 }, 100 { 0x06, 0, 0, 0x00050016 }, 101 { 0x06, 0, 0, 0x00050026 }, 102 { 0x06, 0, 0, 0x0005005f }, 103 { 0x06, 0, 0, 0x7fff0000 }, 104 }; 105 106 struct sock_fprog prog { sizeof(filter) / sizeof(filter[0]), filter }; 107 108 KJ_SYSCALL(prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); 109 KJ_SYSCALL(syscall(__NR_seccomp, SECCOMP_SET_MODE_FILTER, 0, &prog)); 110 } 111 }; 112 113 SetupSeccompForFilesystemTest setupSeccompForFilesystemTest; 114 115 } // namespace 116 117 #define HOLES_NOT_SUPPORTED 118 119 // OK, now run all the regular filesystem tests! 120 #include "filesystem-disk-test.c++" 121 122 #endif 123 #endif 124 #endif 125 126 #if __linux__ && !__x86_64__ 127 // HACK: We may be cross-compiling. Ekam's cross-compiling is currently hacky -- if a test is a 128 // test on the host platform then it needs to be a test on all other targets, too. So add a dummy 129 // test here. 130 // TODO(cleanup): Make Ekam cross-compiling better. 131 #include <kj/test.h> 132 KJ_TEST("old kernel test -- not supported on this architecture") {} 133 #endif