7#include <sys/syscall.h>
12static void check(
int condition,
const char* description) {
13 printf(
"POWER-CONTRACT: %s %s\n", condition ?
"PASS" :
"FAIL", description);
18static int call(uint32_t magic1, uint32_t magic2, uint32_t command) {
20 return syscall(SYS_reboot, magic1, magic2, command, 0);
25 fprintf(stderr,
"power-contract-test must run as root\n");
28 check(call(0, 672274793, 0x01234567) == -1 && errno == EINVAL,
"invalid first magic");
29 check(call(0xfee1dead, 0, 0x01234567) == -1 && errno == EINVAL,
"invalid second magic");
30 check(call(0xfee1dead, 672274793, 0x123) == -1 && errno == EINVAL,
"unknown command");
31 check(call(0xfee1dead, 672274793, 0xa1b2c3d4) == -1 && errno == EINVAL,
"unsupported restart2");
32 check(call(0xfee1dead, 672274793, 0xd000fce2) == -1 && errno == EINVAL,
"unsupported suspend");
33 check(call(0xfee1dead, 672274793, 0x45584543) == -1 && errno == EINVAL,
"unsupported kexec");
34 const uint32_t second[] = {672274793, 85072278, 369367448, 537993216};
35 for (
unsigned i = 0; i <
sizeof(second) /
sizeof(second[0]); ++i) {
36 check(call(0xfee1dead, second[i], 0) == 0,
"CAD_OFF is nonterminal");
37 check(call(0xfee1dead, second[i], 0x89abcdef) == 0,
"CAD_ON is nonterminal");
42 if (setuid(65534) != 0)
44 const uint32_t commands[] = {0x01234567, 0xcdef0123, 0x4321fedc, 0, 0x89abcdef};
45 for (
unsigned i = 0; i <
sizeof(commands) /
sizeof(commands[0]); ++i)
46 if (call(0xfee1dead, 672274793, commands[i]) != -1 || errno != EPERM)
51 check(child > 0 && waitpid(child, &status, 0) == child && WIFEXITED(status) &&
52 WEXITSTATUS(status) == 0,
53 "unprivileged commands denied");
54 printf(
"POWER-CONTRACT: END failures=%d\n", failures);