1 /*- 2 * Copyright (c) 2008-2011 Robert N. M. Watson 3 * Copyright (c) 2011 Jonathan Anderson 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD$ 28 */ 29 30 #ifndef CAP_TEST_H 31 #define CAP_TEST_H 32 33 #include <err.h> 34 35 /* 36 * Define a file required by a test. The test can't complete without the file, 37 * so if we don't have it, just die. 38 */ 39 #define REQUIRE(fd) do { \ 40 if ((fd) < 0) \ 41 err(-1, "%s:%d: Missing required file '%s'", \ 42 __FILE__, __LINE__, #fd); \ 43 } while (0) 44 45 /* Whether a test passed or failed. */ 46 #define PASSED 0 47 #define FAILED 1 48 49 /* A test has failed; print a message and clear the 'success' flag. */ 50 #define FAIL(...) do { \ 51 warn(__VA_ARGS__); \ 52 success = FAILED; \ 53 } while (0) 54 55 /* As above, but do not print the errno message. */ 56 #define FAILX(...) do { \ 57 warnx(__VA_ARGS__); \ 58 success = FAILED; \ 59 } while (0) 60 61 /* Like an assertion, but don't kill the test, just fail and keep going. */ 62 #define CHECK(condition) do { \ 63 if (!(condition)) \ 64 FAILX("%s:%d: Assertion '%s' failed", \ 65 __func__, __LINE__, #condition); \ 66 } while (0) 67 68 /* Make sure that a system call's return value is >= 0. */ 69 #define CHECK_SYSCALL_SUCCEEDS(syscall, ...) do { \ 70 if (syscall(__VA_ARGS__) < 0) \ 71 FAIL("%s() at line %d: %s failed", \ 72 __func__, __LINE__, #syscall); \ 73 } while (0) 74 75 /* Make sure that a system call fails with the correct errno. */ 76 #define CHECK_SYSCALL_FAILS(expected_errno, syscall, ...) do { \ 77 if (syscall(__VA_ARGS__) < 0) { \ 78 if (errno != expected_errno) \ 79 FAIL("%s() at line %d: %s", \ 80 __func__, __LINE__, #syscall); \ 81 } else { \ 82 FAILX("%s() at line %d: %s succeeded; it should've failed", \ 83 __func__, __LINE__, #syscall); \ 84 } \ 85 } while (0) 86 87 /* Make sure that a system call fails, but not with a particular errno. */ 88 #define CHECK_SYSCALL_FAILS_BUT_NOT_WITH(bad_errno, syscall, ...) do { \ 89 if (syscall(__VA_ARGS__) < 0) { \ 90 if (errno == bad_errno) \ 91 FAIL("%s() at line %d: %s", \ 92 __func__, __LINE__, #syscall); \ 93 } else { \ 94 FAILX("%s() at line %d: %s succeeded; it should've failed", \ 95 __func__, __LINE__, #syscall); \ 96 } \ 97 } while (0) 98 99 /* A system call should fail with ECAPMODE. */ 100 #define CHECK_CAPMODE(...) \ 101 CHECK_SYSCALL_FAILS(ECAPMODE, __VA_ARGS__) 102 103 /* A system call should fail, but not with ECAPMODE. */ 104 #define CHECK_NOT_CAPMODE(...) \ 105 CHECK_SYSCALL_FAILS_BUT_NOT_WITH(ECAPMODE, __VA_ARGS__) 106 107 /* A system call should fail with ENOTCAPABLE. */ 108 #define CHECK_NOTCAPABLE(...) \ 109 CHECK_SYSCALL_FAILS(ENOTCAPABLE, __VA_ARGS__) 110 111 /* Ensure that 'rights' are a subset of 'max'. */ 112 #define CHECK_RIGHTS(rights, max) do { \ 113 if ((success == PASSED) && (rights != max)) \ 114 FAILX("Rights of opened file (%jx) > maximum (%jx)", \ 115 (cap_rights_t) rights, (cap_rights_t) max); \ 116 } while (0) 117 118 /* Create a capability from a file descriptor, make sure it succeeds. */ 119 #define MAKE_CAPABILITY(to, from, rights) do { \ 120 cap_rights_t _rights; \ 121 REQUIRE(to = cap_new(from, rights)); \ 122 CHECK_SYSCALL_SUCCEEDS(cap_getrights, to, &_rights); \ 123 if ((success == PASSED) && (_rights != (rights))) \ 124 FAILX("New capability's rights (%jx) != %jx", \ 125 _rights, (cap_rights_t) (rights)); \ 126 } while (0) 127 128 /* 129 * A top-level test should take no arguments and return an integer value, 130 * either PASSED or FAILED. 131 * 132 * Errors such as SIGSEGV will be caught and interpreted as FAILED. 133 */ 134 typedef int (*test_function)(void); 135 136 /* Information about a test. */ 137 struct test { 138 char *t_name; 139 test_function t_run; 140 int t_result; 141 }; 142 143 /* 144 * Run a test in a child process so that cap_enter(2) doesn't mess up 145 * subsequent tests. 146 */ 147 int execute(int id, struct test*); 148 149 int test_capmode(void); 150 int test_capabilities(void); 151 int test_fcntl(void); 152 int test_pdfork(void); 153 int test_pdkill(void); 154 int test_pdwait(void); 155 int test_relative(void); 156 int test_sysctl(void); 157 158 #endif /* CAP_TEST_H */ 159