/* * Check decoding of seccomp SECCOMP_GET_NOTIF_SIZES. * * Copyright (c) 2017-2021 Dmitry V. Levin * Copyright (c) 2021 The strace developers. * All rights reserved. * * SPDX-License-Identifier: GPL-2.0-or-later */ #include "tests.h" #include "scno.h" #include #include #include #include #include #ifndef SECCOMP_GET_NOTIF_SIZES # define SECCOMP_GET_NOTIF_SIZES 3 #endif #ifndef INJECT_RETVAL # define INJECT_RETVAL 0 #endif #if INJECT_RETVAL # define INJ_STR " (INJECTED)" #else # define INJ_STR "" #endif static const char *errstr; static long k_seccomp(const kernel_ulong_t op, const kernel_ulong_t flags, const kernel_ulong_t args) { const long rc = syscall(__NR_seccomp, op, flags, args); errstr = sprintrc(rc); return rc; } int main(void) { uint16_t *sizes = tail_alloc(sizeof(*sizes) * 3); kernel_ulong_t op = (kernel_ulong_t) 0xfacefeed00000000ULL | SECCOMP_GET_NOTIF_SIZES; kernel_ulong_t flags = (kernel_ulong_t) 0xdeadbeef00000000ULL; long rc; rc = k_seccomp(op, flags | 0xdeadbeef, 0); printf("seccomp(SECCOMP_GET_NOTIF_SIZES, 0xdeadbeef, NULL) = %s" INJ_STR "\n", errstr); if (F8ILL_KULONG_SUPPORTED) { rc = k_seccomp(op, flags, f8ill_ptr_to_kulong(0)); printf("seccomp(SECCOMP_GET_NOTIF_SIZES, 0, %#llx) = %s" INJ_STR "\n", (unsigned long long) f8ill_ptr_to_kulong(0), errstr); } rc = k_seccomp(op, flags, (uintptr_t) (sizes + 1)); printf("seccomp(SECCOMP_GET_NOTIF_SIZES, 0, %p) = %s" INJ_STR "\n", sizes + 1, errstr); for (size_t i = 0; i < 2; i++) { sizes[0] = 0xcafe; sizes[1] = 0xfeed; sizes[2] = 0xbeef; rc = k_seccomp(op, flags | (i * 0xdeadc0de), (uintptr_t) sizes); if (rc < 0 && errno != ENOSYS && errno != EINVAL && errno != EPERM) { perror_msg_and_fail("Unexpected seccomp(" "SECCOMP_GET_NOTIF_SIZES) error"); } printf("seccomp(SECCOMP_GET_NOTIF_SIZES, %s, ", i ? "0xdeadc0de" : "0"); if (rc >= 0) { printf("{seccomp_notif=%hu, seccomp_notif_resp=%hu" ", seccomp_data=%hu}", (uint16_t) (INJECT_RETVAL ? 0xcafe : sizes[0]), (uint16_t) (INJECT_RETVAL ? 0xfeed : sizes[1]), (uint16_t) (INJECT_RETVAL ? 0xbeef : sizes[2])); } else { printf("%p", sizes); } printf(") = %s" INJ_STR "\n", errstr); } puts("+++ exited with 0 +++"); return 0; }