brintos

brintos / linux-shallow public Read only

0
0
Text · 124.3 KiB · 8c3a734 Raw
4903 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.4 *5 * Test code for seccomp bpf.6 */7 8#define _GNU_SOURCE9#include <sys/types.h>10 11/*12 * glibc 2.26 and later have SIGSYS in siginfo_t. Before that,13 * we need to use the kernel's siginfo.h file and trick glibc14 * into accepting it.15 */16#if !__GLIBC_PREREQ(2, 26)17# include <asm/siginfo.h>18# define __have_siginfo_t 119# define __have_sigval_t 120# define __have_sigevent_t 121#endif22 23#include <errno.h>24#include <linux/filter.h>25#include <sys/prctl.h>26#include <sys/ptrace.h>27#include <sys/user.h>28#include <linux/prctl.h>29#include <linux/ptrace.h>30#include <linux/seccomp.h>31#include <pthread.h>32#include <semaphore.h>33#include <signal.h>34#include <stddef.h>35#include <stdbool.h>36#include <string.h>37#include <time.h>38#include <limits.h>39#include <linux/elf.h>40#include <sys/uio.h>41#include <sys/utsname.h>42#include <sys/fcntl.h>43#include <sys/mman.h>44#include <sys/times.h>45#include <sys/socket.h>46#include <sys/ioctl.h>47#include <linux/kcmp.h>48#include <sys/resource.h>49#include <sys/capability.h>50 51#include <unistd.h>52#include <sys/syscall.h>53#include <poll.h>54 55#include "../kselftest_harness.h"56#include "../clone3/clone3_selftests.h"57 58/* Attempt to de-conflict with the selftests tree. */59#ifndef SKIP60#define SKIP(s, ...)	XFAIL(s, ##__VA_ARGS__)61#endif62 63#ifndef MIN64#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))65#endif66 67#ifndef PR_SET_PTRACER68# define PR_SET_PTRACER 0x59616d6169#endif70 71#ifndef PR_SET_NO_NEW_PRIVS72#define PR_SET_NO_NEW_PRIVS 3873#define PR_GET_NO_NEW_PRIVS 3974#endif75 76#ifndef PR_SECCOMP_EXT77#define PR_SECCOMP_EXT 4378#endif79 80#ifndef SECCOMP_EXT_ACT81#define SECCOMP_EXT_ACT 182#endif83 84#ifndef SECCOMP_EXT_ACT_TSYNC85#define SECCOMP_EXT_ACT_TSYNC 186#endif87 88#ifndef SECCOMP_MODE_STRICT89#define SECCOMP_MODE_STRICT 190#endif91 92#ifndef SECCOMP_MODE_FILTER93#define SECCOMP_MODE_FILTER 294#endif95 96#ifndef SECCOMP_RET_ALLOW97struct seccomp_data {98	int nr;99	__u32 arch;100	__u64 instruction_pointer;101	__u64 args[6];102};103#endif104 105#ifndef SECCOMP_RET_KILL_PROCESS106#define SECCOMP_RET_KILL_PROCESS 0x80000000U /* kill the process */107#define SECCOMP_RET_KILL_THREAD	 0x00000000U /* kill the thread */108#endif109#ifndef SECCOMP_RET_KILL110#define SECCOMP_RET_KILL	 SECCOMP_RET_KILL_THREAD111#define SECCOMP_RET_TRAP	 0x00030000U /* disallow and force a SIGSYS */112#define SECCOMP_RET_ERRNO	 0x00050000U /* returns an errno */113#define SECCOMP_RET_TRACE	 0x7ff00000U /* pass to a tracer or disallow */114#define SECCOMP_RET_ALLOW	 0x7fff0000U /* allow */115#endif116#ifndef SECCOMP_RET_LOG117#define SECCOMP_RET_LOG		 0x7ffc0000U /* allow after logging */118#endif119 120#ifndef __NR_seccomp121# if defined(__i386__)122#  define __NR_seccomp 354123# elif defined(__x86_64__)124#  define __NR_seccomp 317125# elif defined(__arm__)126#  define __NR_seccomp 383127# elif defined(__aarch64__)128#  define __NR_seccomp 277129# elif defined(__riscv)130#  define __NR_seccomp 277131# elif defined(__csky__)132#  define __NR_seccomp 277133# elif defined(__loongarch__)134#  define __NR_seccomp 277135# elif defined(__hppa__)136#  define __NR_seccomp 338137# elif defined(__powerpc__)138#  define __NR_seccomp 358139# elif defined(__s390__)140#  define __NR_seccomp 348141# elif defined(__xtensa__)142#  define __NR_seccomp 337143# elif defined(__sh__)144#  define __NR_seccomp 372145# elif defined(__mc68000__)146#  define __NR_seccomp 380147# else148#  warning "seccomp syscall number unknown for this architecture"149#  define __NR_seccomp 0xffff150# endif151#endif152 153#ifndef SECCOMP_SET_MODE_STRICT154#define SECCOMP_SET_MODE_STRICT 0155#endif156 157#ifndef SECCOMP_SET_MODE_FILTER158#define SECCOMP_SET_MODE_FILTER 1159#endif160 161#ifndef SECCOMP_GET_ACTION_AVAIL162#define SECCOMP_GET_ACTION_AVAIL 2163#endif164 165#ifndef SECCOMP_GET_NOTIF_SIZES166#define SECCOMP_GET_NOTIF_SIZES 3167#endif168 169#ifndef SECCOMP_FILTER_FLAG_TSYNC170#define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0)171#endif172 173#ifndef SECCOMP_FILTER_FLAG_LOG174#define SECCOMP_FILTER_FLAG_LOG (1UL << 1)175#endif176 177#ifndef SECCOMP_FILTER_FLAG_SPEC_ALLOW178#define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2)179#endif180 181#ifndef PTRACE_SECCOMP_GET_METADATA182#define PTRACE_SECCOMP_GET_METADATA	0x420d183 184struct seccomp_metadata {185	__u64 filter_off;       /* Input: which filter */186	__u64 flags;             /* Output: filter's flags */187};188#endif189 190#ifndef SECCOMP_FILTER_FLAG_NEW_LISTENER191#define SECCOMP_FILTER_FLAG_NEW_LISTENER	(1UL << 3)192#endif193 194#ifndef SECCOMP_RET_USER_NOTIF195#define SECCOMP_RET_USER_NOTIF 0x7fc00000U196 197#define SECCOMP_IOC_MAGIC		'!'198#define SECCOMP_IO(nr)			_IO(SECCOMP_IOC_MAGIC, nr)199#define SECCOMP_IOR(nr, type)		_IOR(SECCOMP_IOC_MAGIC, nr, type)200#define SECCOMP_IOW(nr, type)		_IOW(SECCOMP_IOC_MAGIC, nr, type)201#define SECCOMP_IOWR(nr, type)		_IOWR(SECCOMP_IOC_MAGIC, nr, type)202 203/* Flags for seccomp notification fd ioctl. */204#define SECCOMP_IOCTL_NOTIF_RECV	SECCOMP_IOWR(0, struct seccomp_notif)205#define SECCOMP_IOCTL_NOTIF_SEND	SECCOMP_IOWR(1,	\206						struct seccomp_notif_resp)207#define SECCOMP_IOCTL_NOTIF_ID_VALID	SECCOMP_IOW(2, __u64)208 209struct seccomp_notif {210	__u64 id;211	__u32 pid;212	__u32 flags;213	struct seccomp_data data;214};215 216struct seccomp_notif_resp {217	__u64 id;218	__s64 val;219	__s32 error;220	__u32 flags;221};222 223struct seccomp_notif_sizes {224	__u16 seccomp_notif;225	__u16 seccomp_notif_resp;226	__u16 seccomp_data;227};228#endif229 230#ifndef SECCOMP_IOCTL_NOTIF_ADDFD231/* On success, the return value is the remote process's added fd number */232#define SECCOMP_IOCTL_NOTIF_ADDFD	SECCOMP_IOW(3,	\233						struct seccomp_notif_addfd)234 235/* valid flags for seccomp_notif_addfd */236#define SECCOMP_ADDFD_FLAG_SETFD	(1UL << 0) /* Specify remote fd */237 238struct seccomp_notif_addfd {239	__u64 id;240	__u32 flags;241	__u32 srcfd;242	__u32 newfd;243	__u32 newfd_flags;244};245#endif246 247#ifndef SECCOMP_ADDFD_FLAG_SEND248#define SECCOMP_ADDFD_FLAG_SEND	(1UL << 1) /* Addfd and return it, atomically */249#endif250 251struct seccomp_notif_addfd_small {252	__u64 id;253	char weird[4];254};255#define SECCOMP_IOCTL_NOTIF_ADDFD_SMALL	\256	SECCOMP_IOW(3, struct seccomp_notif_addfd_small)257 258struct seccomp_notif_addfd_big {259	union {260		struct seccomp_notif_addfd addfd;261		char buf[sizeof(struct seccomp_notif_addfd) + 8];262	};263};264#define SECCOMP_IOCTL_NOTIF_ADDFD_BIG	\265	SECCOMP_IOWR(3, struct seccomp_notif_addfd_big)266 267#ifndef PTRACE_EVENTMSG_SYSCALL_ENTRY268#define PTRACE_EVENTMSG_SYSCALL_ENTRY	1269#define PTRACE_EVENTMSG_SYSCALL_EXIT	2270#endif271 272#ifndef SECCOMP_USER_NOTIF_FLAG_CONTINUE273#define SECCOMP_USER_NOTIF_FLAG_CONTINUE 0x00000001274#endif275 276#ifndef SECCOMP_FILTER_FLAG_TSYNC_ESRCH277#define SECCOMP_FILTER_FLAG_TSYNC_ESRCH (1UL << 4)278#endif279 280#ifndef SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV281#define SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV (1UL << 5)282#endif283 284#ifndef seccomp285int seccomp(unsigned int op, unsigned int flags, void *args)286{287	errno = 0;288	return syscall(__NR_seccomp, op, flags, args);289}290#endif291 292#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__293#define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n]))294#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__295#define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n]) + sizeof(__u32))296#else297#error "wut? Unknown __BYTE_ORDER__?!"298#endif299 300#define SIBLING_EXIT_UNKILLED	0xbadbeef301#define SIBLING_EXIT_FAILURE	0xbadface302#define SIBLING_EXIT_NEWPRIVS	0xbadfeed303 304static int __filecmp(pid_t pid1, pid_t pid2, int fd1, int fd2)305{306#ifdef __NR_kcmp307	errno = 0;308	return syscall(__NR_kcmp, pid1, pid2, KCMP_FILE, fd1, fd2);309#else310	errno = ENOSYS;311	return -1;312#endif313}314 315/* Have TH_LOG report actual location filecmp() is used. */316#define filecmp(pid1, pid2, fd1, fd2)	({		\317	int _ret;					\318							\319	_ret = __filecmp(pid1, pid2, fd1, fd2);		\320	if (_ret != 0) {				\321		if (_ret < 0 && errno == ENOSYS) {	\322			TH_LOG("kcmp() syscall missing (test is less accurate)");\323			_ret = 0;			\324		}					\325	}						\326	_ret; })327 328TEST(kcmp)329{330	int ret;331 332	ret = __filecmp(getpid(), getpid(), 1, 1);333	EXPECT_EQ(ret, 0);334	if (ret != 0 && errno == ENOSYS)335		SKIP(return, "Kernel does not support kcmp() (missing CONFIG_KCMP?)");336}337 338TEST(mode_strict_support)339{340	long ret;341 342	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, NULL, NULL, NULL);343	ASSERT_EQ(0, ret) {344		TH_LOG("Kernel does not support CONFIG_SECCOMP");345	}346	syscall(__NR_exit, 0);347}348 349TEST_SIGNAL(mode_strict_cannot_call_prctl, SIGKILL)350{351	long ret;352 353	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, NULL, NULL, NULL);354	ASSERT_EQ(0, ret) {355		TH_LOG("Kernel does not support CONFIG_SECCOMP");356	}357	syscall(__NR_prctl, PR_SET_SECCOMP, SECCOMP_MODE_FILTER,358		NULL, NULL, NULL);359	EXPECT_FALSE(true) {360		TH_LOG("Unreachable!");361	}362}363 364/* Note! This doesn't test no new privs behavior */365TEST(no_new_privs_support)366{367	long ret;368 369	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);370	EXPECT_EQ(0, ret) {371		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");372	}373}374 375/* Tests kernel support by checking for a copy_from_user() fault on NULL. */376TEST(mode_filter_support)377{378	long ret;379 380	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, NULL, 0, 0);381	ASSERT_EQ(0, ret) {382		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");383	}384	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, NULL, NULL);385	EXPECT_EQ(-1, ret);386	EXPECT_EQ(EFAULT, errno) {387		TH_LOG("Kernel does not support CONFIG_SECCOMP_FILTER!");388	}389}390 391TEST(mode_filter_without_nnp)392{393	struct sock_filter filter[] = {394		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),395	};396	struct sock_fprog prog = {397		.len = (unsigned short)ARRAY_SIZE(filter),398		.filter = filter,399	};400	long ret;401	cap_t cap = cap_get_proc();402	cap_flag_value_t is_cap_sys_admin = 0;403 404	ret = prctl(PR_GET_NO_NEW_PRIVS, 0, NULL, 0, 0);405	ASSERT_LE(0, ret) {406		TH_LOG("Expected 0 or unsupported for NO_NEW_PRIVS");407	}408	errno = 0;409	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);410	/* Succeeds with CAP_SYS_ADMIN, fails without */411	cap_get_flag(cap, CAP_SYS_ADMIN, CAP_EFFECTIVE, &is_cap_sys_admin);412	if (!is_cap_sys_admin) {413		EXPECT_EQ(-1, ret);414		EXPECT_EQ(EACCES, errno);415	} else {416		EXPECT_EQ(0, ret);417	}418}419 420#define MAX_INSNS_PER_PATH 32768421 422TEST(filter_size_limits)423{424	int i;425	int count = BPF_MAXINSNS + 1;426	struct sock_filter allow[] = {427		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),428	};429	struct sock_filter *filter;430	struct sock_fprog prog = { };431	long ret;432 433	filter = calloc(count, sizeof(*filter));434	ASSERT_NE(NULL, filter);435 436	for (i = 0; i < count; i++)437		filter[i] = allow[0];438 439	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);440	ASSERT_EQ(0, ret);441 442	prog.filter = filter;443	prog.len = count;444 445	/* Too many filter instructions in a single filter. */446	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);447	ASSERT_NE(0, ret) {448		TH_LOG("Installing %d insn filter was allowed", prog.len);449	}450 451	/* One less is okay, though. */452	prog.len -= 1;453	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);454	ASSERT_EQ(0, ret) {455		TH_LOG("Installing %d insn filter wasn't allowed", prog.len);456	}457}458 459TEST(filter_chain_limits)460{461	int i;462	int count = BPF_MAXINSNS;463	struct sock_filter allow[] = {464		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),465	};466	struct sock_filter *filter;467	struct sock_fprog prog = { };468	long ret;469 470	filter = calloc(count, sizeof(*filter));471	ASSERT_NE(NULL, filter);472 473	for (i = 0; i < count; i++)474		filter[i] = allow[0];475 476	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);477	ASSERT_EQ(0, ret);478 479	prog.filter = filter;480	prog.len = 1;481 482	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);483	ASSERT_EQ(0, ret);484 485	prog.len = count;486 487	/* Too many total filter instructions. */488	for (i = 0; i < MAX_INSNS_PER_PATH; i++) {489		ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);490		if (ret != 0)491			break;492	}493	ASSERT_NE(0, ret) {494		TH_LOG("Allowed %d %d-insn filters (total with penalties:%d)",495		       i, count, i * (count + 4));496	}497}498 499TEST(mode_filter_cannot_move_to_strict)500{501	struct sock_filter filter[] = {502		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),503	};504	struct sock_fprog prog = {505		.len = (unsigned short)ARRAY_SIZE(filter),506		.filter = filter,507	};508	long ret;509 510	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);511	ASSERT_EQ(0, ret);512 513	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);514	ASSERT_EQ(0, ret);515 516	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, NULL, 0, 0);517	EXPECT_EQ(-1, ret);518	EXPECT_EQ(EINVAL, errno);519}520 521 522TEST(mode_filter_get_seccomp)523{524	struct sock_filter filter[] = {525		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),526	};527	struct sock_fprog prog = {528		.len = (unsigned short)ARRAY_SIZE(filter),529		.filter = filter,530	};531	long ret;532 533	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);534	ASSERT_EQ(0, ret);535 536	ret = prctl(PR_GET_SECCOMP, 0, 0, 0, 0);537	EXPECT_EQ(0, ret);538 539	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);540	ASSERT_EQ(0, ret);541 542	ret = prctl(PR_GET_SECCOMP, 0, 0, 0, 0);543	EXPECT_EQ(2, ret);544}545 546 547TEST(ALLOW_all)548{549	struct sock_filter filter[] = {550		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),551	};552	struct sock_fprog prog = {553		.len = (unsigned short)ARRAY_SIZE(filter),554		.filter = filter,555	};556	long ret;557 558	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);559	ASSERT_EQ(0, ret);560 561	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);562	ASSERT_EQ(0, ret);563}564 565TEST(empty_prog)566{567	struct sock_filter filter[] = {568	};569	struct sock_fprog prog = {570		.len = (unsigned short)ARRAY_SIZE(filter),571		.filter = filter,572	};573	long ret;574 575	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);576	ASSERT_EQ(0, ret);577 578	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);579	EXPECT_EQ(-1, ret);580	EXPECT_EQ(EINVAL, errno);581}582 583TEST(log_all)584{585	struct sock_filter filter[] = {586		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_LOG),587	};588	struct sock_fprog prog = {589		.len = (unsigned short)ARRAY_SIZE(filter),590		.filter = filter,591	};592	long ret;593	pid_t parent = getppid();594 595	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);596	ASSERT_EQ(0, ret);597 598	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);599	ASSERT_EQ(0, ret);600 601	/* getppid() should succeed and be logged (no check for logging) */602	EXPECT_EQ(parent, syscall(__NR_getppid));603}604 605TEST_SIGNAL(unknown_ret_is_kill_inside, SIGSYS)606{607	struct sock_filter filter[] = {608		BPF_STMT(BPF_RET|BPF_K, 0x10000000U),609	};610	struct sock_fprog prog = {611		.len = (unsigned short)ARRAY_SIZE(filter),612		.filter = filter,613	};614	long ret;615 616	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);617	ASSERT_EQ(0, ret);618 619	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);620	ASSERT_EQ(0, ret);621	EXPECT_EQ(0, syscall(__NR_getpid)) {622		TH_LOG("getpid() shouldn't ever return");623	}624}625 626/* return code >= 0x80000000 is unused. */627TEST_SIGNAL(unknown_ret_is_kill_above_allow, SIGSYS)628{629	struct sock_filter filter[] = {630		BPF_STMT(BPF_RET|BPF_K, 0x90000000U),631	};632	struct sock_fprog prog = {633		.len = (unsigned short)ARRAY_SIZE(filter),634		.filter = filter,635	};636	long ret;637 638	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);639	ASSERT_EQ(0, ret);640 641	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);642	ASSERT_EQ(0, ret);643	EXPECT_EQ(0, syscall(__NR_getpid)) {644		TH_LOG("getpid() shouldn't ever return");645	}646}647 648TEST_SIGNAL(KILL_all, SIGSYS)649{650	struct sock_filter filter[] = {651		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),652	};653	struct sock_fprog prog = {654		.len = (unsigned short)ARRAY_SIZE(filter),655		.filter = filter,656	};657	long ret;658 659	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);660	ASSERT_EQ(0, ret);661 662	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);663	ASSERT_EQ(0, ret);664}665 666TEST_SIGNAL(KILL_one, SIGSYS)667{668	struct sock_filter filter[] = {669		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,670			offsetof(struct seccomp_data, nr)),671		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 0, 1),672		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),673		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),674	};675	struct sock_fprog prog = {676		.len = (unsigned short)ARRAY_SIZE(filter),677		.filter = filter,678	};679	long ret;680	pid_t parent = getppid();681 682	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);683	ASSERT_EQ(0, ret);684 685	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);686	ASSERT_EQ(0, ret);687 688	EXPECT_EQ(parent, syscall(__NR_getppid));689	/* getpid() should never return. */690	EXPECT_EQ(0, syscall(__NR_getpid));691}692 693TEST_SIGNAL(KILL_one_arg_one, SIGSYS)694{695	void *fatal_address;696	struct sock_filter filter[] = {697		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,698			offsetof(struct seccomp_data, nr)),699		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_times, 1, 0),700		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),701		/* Only both with lower 32-bit for now. */702		BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(0)),703		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K,704			(unsigned long)&fatal_address, 0, 1),705		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),706		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),707	};708	struct sock_fprog prog = {709		.len = (unsigned short)ARRAY_SIZE(filter),710		.filter = filter,711	};712	long ret;713	pid_t parent = getppid();714	struct tms timebuf;715	clock_t clock = times(&timebuf);716 717	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);718	ASSERT_EQ(0, ret);719 720	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);721	ASSERT_EQ(0, ret);722 723	EXPECT_EQ(parent, syscall(__NR_getppid));724	EXPECT_LE(clock, syscall(__NR_times, &timebuf));725	/* times() should never return. */726	EXPECT_EQ(0, syscall(__NR_times, &fatal_address));727}728 729TEST_SIGNAL(KILL_one_arg_six, SIGSYS)730{731#ifndef __NR_mmap2732	int sysno = __NR_mmap;733#else734	int sysno = __NR_mmap2;735#endif736	struct sock_filter filter[] = {737		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,738			offsetof(struct seccomp_data, nr)),739		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, sysno, 1, 0),740		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),741		/* Only both with lower 32-bit for now. */742		BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(5)),743		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x0C0FFEE, 0, 1),744		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),745		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),746	};747	struct sock_fprog prog = {748		.len = (unsigned short)ARRAY_SIZE(filter),749		.filter = filter,750	};751	long ret;752	pid_t parent = getppid();753	int fd;754	void *map1, *map2;755	int page_size = sysconf(_SC_PAGESIZE);756 757	ASSERT_LT(0, page_size);758 759	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);760	ASSERT_EQ(0, ret);761 762	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);763	ASSERT_EQ(0, ret);764 765	fd = open("/dev/zero", O_RDONLY);766	ASSERT_NE(-1, fd);767 768	EXPECT_EQ(parent, syscall(__NR_getppid));769	map1 = (void *)syscall(sysno,770		NULL, page_size, PROT_READ, MAP_PRIVATE, fd, page_size);771	EXPECT_NE(MAP_FAILED, map1);772	/* mmap2() should never return. */773	map2 = (void *)syscall(sysno,774		 NULL, page_size, PROT_READ, MAP_PRIVATE, fd, 0x0C0FFEE);775	EXPECT_EQ(MAP_FAILED, map2);776 777	/* The test failed, so clean up the resources. */778	munmap(map1, page_size);779	munmap(map2, page_size);780	close(fd);781}782 783/* This is a thread task to die via seccomp filter violation. */784void *kill_thread(void *data)785{786	bool die = (bool)data;787 788	if (die) {789		syscall(__NR_getpid);790		return (void *)SIBLING_EXIT_FAILURE;791	}792 793	return (void *)SIBLING_EXIT_UNKILLED;794}795 796enum kill_t {797	KILL_THREAD,798	KILL_PROCESS,799	RET_UNKNOWN800};801 802/* Prepare a thread that will kill itself or both of us. */803void kill_thread_or_group(struct __test_metadata *_metadata,804			  enum kill_t kill_how)805{806	pthread_t thread;807	void *status;808	/* Kill only when calling __NR_getpid. */809	struct sock_filter filter_thread[] = {810		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,811			offsetof(struct seccomp_data, nr)),812		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 0, 1),813		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL_THREAD),814		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),815	};816	struct sock_fprog prog_thread = {817		.len = (unsigned short)ARRAY_SIZE(filter_thread),818		.filter = filter_thread,819	};820	int kill = kill_how == KILL_PROCESS ? SECCOMP_RET_KILL_PROCESS : 0xAAAAAAAA;821	struct sock_filter filter_process[] = {822		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,823			offsetof(struct seccomp_data, nr)),824		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 0, 1),825		BPF_STMT(BPF_RET|BPF_K, kill),826		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),827	};828	struct sock_fprog prog_process = {829		.len = (unsigned short)ARRAY_SIZE(filter_process),830		.filter = filter_process,831	};832 833	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {834		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");835	}836 837	ASSERT_EQ(0, seccomp(SECCOMP_SET_MODE_FILTER, 0,838			     kill_how == KILL_THREAD ? &prog_thread839						     : &prog_process));840 841	/*842	 * Add the KILL_THREAD rule again to make sure that the KILL_PROCESS843	 * flag cannot be downgraded by a new filter.844	 */845	if (kill_how == KILL_PROCESS)846		ASSERT_EQ(0, seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog_thread));847 848	/* Start a thread that will exit immediately. */849	ASSERT_EQ(0, pthread_create(&thread, NULL, kill_thread, (void *)false));850	ASSERT_EQ(0, pthread_join(thread, &status));851	ASSERT_EQ(SIBLING_EXIT_UNKILLED, (unsigned long)status);852 853	/* Start a thread that will die immediately. */854	ASSERT_EQ(0, pthread_create(&thread, NULL, kill_thread, (void *)true));855	ASSERT_EQ(0, pthread_join(thread, &status));856	ASSERT_NE(SIBLING_EXIT_FAILURE, (unsigned long)status);857 858	/*859	 * If we get here, only the spawned thread died. Let the parent know860	 * the whole process didn't die (i.e. this thread, the spawner,861	 * stayed running).862	 */863	exit(42);864}865 866TEST(KILL_thread)867{868	int status;869	pid_t child_pid;870 871	child_pid = fork();872	ASSERT_LE(0, child_pid);873	if (child_pid == 0) {874		kill_thread_or_group(_metadata, KILL_THREAD);875		_exit(38);876	}877 878	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));879 880	/* If only the thread was killed, we'll see exit 42. */881	ASSERT_TRUE(WIFEXITED(status));882	ASSERT_EQ(42, WEXITSTATUS(status));883}884 885TEST(KILL_process)886{887	int status;888	pid_t child_pid;889 890	child_pid = fork();891	ASSERT_LE(0, child_pid);892	if (child_pid == 0) {893		kill_thread_or_group(_metadata, KILL_PROCESS);894		_exit(38);895	}896 897	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));898 899	/* If the entire process was killed, we'll see SIGSYS. */900	ASSERT_TRUE(WIFSIGNALED(status));901	ASSERT_EQ(SIGSYS, WTERMSIG(status));902}903 904TEST(KILL_unknown)905{906	int status;907	pid_t child_pid;908 909	child_pid = fork();910	ASSERT_LE(0, child_pid);911	if (child_pid == 0) {912		kill_thread_or_group(_metadata, RET_UNKNOWN);913		_exit(38);914	}915 916	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));917 918	/* If the entire process was killed, we'll see SIGSYS. */919	EXPECT_TRUE(WIFSIGNALED(status)) {920		TH_LOG("Unknown SECCOMP_RET is only killing the thread?");921	}922	ASSERT_EQ(SIGSYS, WTERMSIG(status));923}924 925/* TODO(wad) add 64-bit versus 32-bit arg tests. */926TEST(arg_out_of_range)927{928	struct sock_filter filter[] = {929		BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(6)),930		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),931	};932	struct sock_fprog prog = {933		.len = (unsigned short)ARRAY_SIZE(filter),934		.filter = filter,935	};936	long ret;937 938	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);939	ASSERT_EQ(0, ret);940 941	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);942	EXPECT_EQ(-1, ret);943	EXPECT_EQ(EINVAL, errno);944}945 946#define ERRNO_FILTER(name, errno)					\947	struct sock_filter _read_filter_##name[] = {			\948		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,				\949			offsetof(struct seccomp_data, nr)),		\950		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 0, 1),	\951		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | errno),	\952		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),		\953	};								\954	struct sock_fprog prog_##name = {				\955		.len = (unsigned short)ARRAY_SIZE(_read_filter_##name),	\956		.filter = _read_filter_##name,				\957	}958 959/* Make sure basic errno values are correctly passed through a filter. */960TEST(ERRNO_valid)961{962	ERRNO_FILTER(valid, E2BIG);963	long ret;964	pid_t parent = getppid();965 966	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);967	ASSERT_EQ(0, ret);968 969	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog_valid);970	ASSERT_EQ(0, ret);971 972	EXPECT_EQ(parent, syscall(__NR_getppid));973	EXPECT_EQ(-1, read(-1, NULL, 0));974	EXPECT_EQ(E2BIG, errno);975}976 977/* Make sure an errno of zero is correctly handled by the arch code. */978TEST(ERRNO_zero)979{980	ERRNO_FILTER(zero, 0);981	long ret;982	pid_t parent = getppid();983 984	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);985	ASSERT_EQ(0, ret);986 987	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog_zero);988	ASSERT_EQ(0, ret);989 990	EXPECT_EQ(parent, syscall(__NR_getppid));991	/* "errno" of 0 is ok. */992	EXPECT_EQ(0, read(-1, NULL, 0));993}994 995/*996 * The SECCOMP_RET_DATA mask is 16 bits wide, but errno is smaller.997 * This tests that the errno value gets capped correctly, fixed by998 * 580c57f10768 ("seccomp: cap SECCOMP_RET_ERRNO data to MAX_ERRNO").999 */1000TEST(ERRNO_capped)1001{1002	ERRNO_FILTER(capped, 4096);1003	long ret;1004	pid_t parent = getppid();1005 1006	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1007	ASSERT_EQ(0, ret);1008 1009	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog_capped);1010	ASSERT_EQ(0, ret);1011 1012	EXPECT_EQ(parent, syscall(__NR_getppid));1013	EXPECT_EQ(-1, read(-1, NULL, 0));1014	EXPECT_EQ(4095, errno);1015}1016 1017/*1018 * Filters are processed in reverse order: last applied is executed first.1019 * Since only the SECCOMP_RET_ACTION mask is tested for return values, the1020 * SECCOMP_RET_DATA mask results will follow the most recently applied1021 * matching filter return (and not the lowest or highest value).1022 */1023TEST(ERRNO_order)1024{1025	ERRNO_FILTER(first,  11);1026	ERRNO_FILTER(second, 13);1027	ERRNO_FILTER(third,  12);1028	long ret;1029	pid_t parent = getppid();1030 1031	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1032	ASSERT_EQ(0, ret);1033 1034	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog_first);1035	ASSERT_EQ(0, ret);1036 1037	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog_second);1038	ASSERT_EQ(0, ret);1039 1040	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog_third);1041	ASSERT_EQ(0, ret);1042 1043	EXPECT_EQ(parent, syscall(__NR_getppid));1044	EXPECT_EQ(-1, read(-1, NULL, 0));1045	EXPECT_EQ(12, errno);1046}1047 1048FIXTURE(TRAP) {1049	struct sock_fprog prog;1050};1051 1052FIXTURE_SETUP(TRAP)1053{1054	struct sock_filter filter[] = {1055		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,1056			offsetof(struct seccomp_data, nr)),1057		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 0, 1),1058		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRAP),1059		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),1060	};1061 1062	memset(&self->prog, 0, sizeof(self->prog));1063	self->prog.filter = malloc(sizeof(filter));1064	ASSERT_NE(NULL, self->prog.filter);1065	memcpy(self->prog.filter, filter, sizeof(filter));1066	self->prog.len = (unsigned short)ARRAY_SIZE(filter);1067}1068 1069FIXTURE_TEARDOWN(TRAP)1070{1071	if (self->prog.filter)1072		free(self->prog.filter);1073}1074 1075TEST_F_SIGNAL(TRAP, dfl, SIGSYS)1076{1077	long ret;1078 1079	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1080	ASSERT_EQ(0, ret);1081 1082	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog);1083	ASSERT_EQ(0, ret);1084	syscall(__NR_getpid);1085}1086 1087/* Ensure that SIGSYS overrides SIG_IGN */1088TEST_F_SIGNAL(TRAP, ign, SIGSYS)1089{1090	long ret;1091 1092	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1093	ASSERT_EQ(0, ret);1094 1095	signal(SIGSYS, SIG_IGN);1096 1097	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog);1098	ASSERT_EQ(0, ret);1099	syscall(__NR_getpid);1100}1101 1102static siginfo_t TRAP_info;1103static volatile int TRAP_nr;1104static void TRAP_action(int nr, siginfo_t *info, void *void_context)1105{1106	memcpy(&TRAP_info, info, sizeof(TRAP_info));1107	TRAP_nr = nr;1108}1109 1110TEST_F(TRAP, handler)1111{1112	int ret, test;1113	struct sigaction act;1114	sigset_t mask;1115 1116	memset(&act, 0, sizeof(act));1117	sigemptyset(&mask);1118	sigaddset(&mask, SIGSYS);1119 1120	act.sa_sigaction = &TRAP_action;1121	act.sa_flags = SA_SIGINFO;1122	ret = sigaction(SIGSYS, &act, NULL);1123	ASSERT_EQ(0, ret) {1124		TH_LOG("sigaction failed");1125	}1126	ret = sigprocmask(SIG_UNBLOCK, &mask, NULL);1127	ASSERT_EQ(0, ret) {1128		TH_LOG("sigprocmask failed");1129	}1130 1131	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1132	ASSERT_EQ(0, ret);1133	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog);1134	ASSERT_EQ(0, ret);1135	TRAP_nr = 0;1136	memset(&TRAP_info, 0, sizeof(TRAP_info));1137	/* Expect the registers to be rolled back. (nr = error) may vary1138	 * based on arch. */1139	ret = syscall(__NR_getpid);1140	/* Silence gcc warning about volatile. */1141	test = TRAP_nr;1142	EXPECT_EQ(SIGSYS, test);1143	struct local_sigsys {1144		void *_call_addr;	/* calling user insn */1145		int _syscall;		/* triggering system call number */1146		unsigned int _arch;	/* AUDIT_ARCH_* of syscall */1147	} *sigsys = (struct local_sigsys *)1148#ifdef si_syscall1149		&(TRAP_info.si_call_addr);1150#else1151		&TRAP_info.si_pid;1152#endif1153	EXPECT_EQ(__NR_getpid, sigsys->_syscall);1154	/* Make sure arch is non-zero. */1155	EXPECT_NE(0, sigsys->_arch);1156	EXPECT_NE(0, (unsigned long)sigsys->_call_addr);1157}1158 1159FIXTURE(precedence) {1160	struct sock_fprog allow;1161	struct sock_fprog log;1162	struct sock_fprog trace;1163	struct sock_fprog error;1164	struct sock_fprog trap;1165	struct sock_fprog kill;1166};1167 1168FIXTURE_SETUP(precedence)1169{1170	struct sock_filter allow_insns[] = {1171		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),1172	};1173	struct sock_filter log_insns[] = {1174		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,1175			offsetof(struct seccomp_data, nr)),1176		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),1177		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),1178		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_LOG),1179	};1180	struct sock_filter trace_insns[] = {1181		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,1182			offsetof(struct seccomp_data, nr)),1183		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),1184		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),1185		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE),1186	};1187	struct sock_filter error_insns[] = {1188		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,1189			offsetof(struct seccomp_data, nr)),1190		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),1191		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),1192		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO),1193	};1194	struct sock_filter trap_insns[] = {1195		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,1196			offsetof(struct seccomp_data, nr)),1197		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),1198		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),1199		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRAP),1200	};1201	struct sock_filter kill_insns[] = {1202		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,1203			offsetof(struct seccomp_data, nr)),1204		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),1205		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),1206		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),1207	};1208 1209	memset(self, 0, sizeof(*self));1210#define FILTER_ALLOC(_x) \1211	self->_x.filter = malloc(sizeof(_x##_insns)); \1212	ASSERT_NE(NULL, self->_x.filter); \1213	memcpy(self->_x.filter, &_x##_insns, sizeof(_x##_insns)); \1214	self->_x.len = (unsigned short)ARRAY_SIZE(_x##_insns)1215	FILTER_ALLOC(allow);1216	FILTER_ALLOC(log);1217	FILTER_ALLOC(trace);1218	FILTER_ALLOC(error);1219	FILTER_ALLOC(trap);1220	FILTER_ALLOC(kill);1221}1222 1223FIXTURE_TEARDOWN(precedence)1224{1225#define FILTER_FREE(_x) if (self->_x.filter) free(self->_x.filter)1226	FILTER_FREE(allow);1227	FILTER_FREE(log);1228	FILTER_FREE(trace);1229	FILTER_FREE(error);1230	FILTER_FREE(trap);1231	FILTER_FREE(kill);1232}1233 1234TEST_F(precedence, allow_ok)1235{1236	pid_t parent, res = 0;1237	long ret;1238 1239	parent = getppid();1240	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1241	ASSERT_EQ(0, ret);1242 1243	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);1244	ASSERT_EQ(0, ret);1245	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);1246	ASSERT_EQ(0, ret);1247	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);1248	ASSERT_EQ(0, ret);1249	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);1250	ASSERT_EQ(0, ret);1251	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);1252	ASSERT_EQ(0, ret);1253	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->kill);1254	ASSERT_EQ(0, ret);1255	/* Should work just fine. */1256	res = syscall(__NR_getppid);1257	EXPECT_EQ(parent, res);1258}1259 1260TEST_F_SIGNAL(precedence, kill_is_highest, SIGSYS)1261{1262	pid_t parent, res = 0;1263	long ret;1264 1265	parent = getppid();1266	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1267	ASSERT_EQ(0, ret);1268 1269	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);1270	ASSERT_EQ(0, ret);1271	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);1272	ASSERT_EQ(0, ret);1273	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);1274	ASSERT_EQ(0, ret);1275	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);1276	ASSERT_EQ(0, ret);1277	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);1278	ASSERT_EQ(0, ret);1279	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->kill);1280	ASSERT_EQ(0, ret);1281	/* Should work just fine. */1282	res = syscall(__NR_getppid);1283	EXPECT_EQ(parent, res);1284	/* getpid() should never return. */1285	res = syscall(__NR_getpid);1286	EXPECT_EQ(0, res);1287}1288 1289TEST_F_SIGNAL(precedence, kill_is_highest_in_any_order, SIGSYS)1290{1291	pid_t parent;1292	long ret;1293 1294	parent = getppid();1295	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1296	ASSERT_EQ(0, ret);1297 1298	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);1299	ASSERT_EQ(0, ret);1300	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->kill);1301	ASSERT_EQ(0, ret);1302	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);1303	ASSERT_EQ(0, ret);1304	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);1305	ASSERT_EQ(0, ret);1306	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);1307	ASSERT_EQ(0, ret);1308	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);1309	ASSERT_EQ(0, ret);1310	/* Should work just fine. */1311	EXPECT_EQ(parent, syscall(__NR_getppid));1312	/* getpid() should never return. */1313	EXPECT_EQ(0, syscall(__NR_getpid));1314}1315 1316TEST_F_SIGNAL(precedence, trap_is_second, SIGSYS)1317{1318	pid_t parent;1319	long ret;1320 1321	parent = getppid();1322	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1323	ASSERT_EQ(0, ret);1324 1325	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);1326	ASSERT_EQ(0, ret);1327	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);1328	ASSERT_EQ(0, ret);1329	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);1330	ASSERT_EQ(0, ret);1331	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);1332	ASSERT_EQ(0, ret);1333	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);1334	ASSERT_EQ(0, ret);1335	/* Should work just fine. */1336	EXPECT_EQ(parent, syscall(__NR_getppid));1337	/* getpid() should never return. */1338	EXPECT_EQ(0, syscall(__NR_getpid));1339}1340 1341TEST_F_SIGNAL(precedence, trap_is_second_in_any_order, SIGSYS)1342{1343	pid_t parent;1344	long ret;1345 1346	parent = getppid();1347	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1348	ASSERT_EQ(0, ret);1349 1350	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);1351	ASSERT_EQ(0, ret);1352	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);1353	ASSERT_EQ(0, ret);1354	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);1355	ASSERT_EQ(0, ret);1356	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);1357	ASSERT_EQ(0, ret);1358	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);1359	ASSERT_EQ(0, ret);1360	/* Should work just fine. */1361	EXPECT_EQ(parent, syscall(__NR_getppid));1362	/* getpid() should never return. */1363	EXPECT_EQ(0, syscall(__NR_getpid));1364}1365 1366TEST_F(precedence, errno_is_third)1367{1368	pid_t parent;1369	long ret;1370 1371	parent = getppid();1372	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1373	ASSERT_EQ(0, ret);1374 1375	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);1376	ASSERT_EQ(0, ret);1377	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);1378	ASSERT_EQ(0, ret);1379	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);1380	ASSERT_EQ(0, ret);1381	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);1382	ASSERT_EQ(0, ret);1383	/* Should work just fine. */1384	EXPECT_EQ(parent, syscall(__NR_getppid));1385	EXPECT_EQ(0, syscall(__NR_getpid));1386}1387 1388TEST_F(precedence, errno_is_third_in_any_order)1389{1390	pid_t parent;1391	long ret;1392 1393	parent = getppid();1394	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1395	ASSERT_EQ(0, ret);1396 1397	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);1398	ASSERT_EQ(0, ret);1399	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);1400	ASSERT_EQ(0, ret);1401	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);1402	ASSERT_EQ(0, ret);1403	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);1404	ASSERT_EQ(0, ret);1405	/* Should work just fine. */1406	EXPECT_EQ(parent, syscall(__NR_getppid));1407	EXPECT_EQ(0, syscall(__NR_getpid));1408}1409 1410TEST_F(precedence, trace_is_fourth)1411{1412	pid_t parent;1413	long ret;1414 1415	parent = getppid();1416	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1417	ASSERT_EQ(0, ret);1418 1419	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);1420	ASSERT_EQ(0, ret);1421	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);1422	ASSERT_EQ(0, ret);1423	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);1424	ASSERT_EQ(0, ret);1425	/* Should work just fine. */1426	EXPECT_EQ(parent, syscall(__NR_getppid));1427	/* No ptracer */1428	EXPECT_EQ(-1, syscall(__NR_getpid));1429}1430 1431TEST_F(precedence, trace_is_fourth_in_any_order)1432{1433	pid_t parent;1434	long ret;1435 1436	parent = getppid();1437	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1438	ASSERT_EQ(0, ret);1439 1440	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);1441	ASSERT_EQ(0, ret);1442	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);1443	ASSERT_EQ(0, ret);1444	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);1445	ASSERT_EQ(0, ret);1446	/* Should work just fine. */1447	EXPECT_EQ(parent, syscall(__NR_getppid));1448	/* No ptracer */1449	EXPECT_EQ(-1, syscall(__NR_getpid));1450}1451 1452TEST_F(precedence, log_is_fifth)1453{1454	pid_t mypid, parent;1455	long ret;1456 1457	mypid = getpid();1458	parent = getppid();1459	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1460	ASSERT_EQ(0, ret);1461 1462	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);1463	ASSERT_EQ(0, ret);1464	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);1465	ASSERT_EQ(0, ret);1466	/* Should work just fine. */1467	EXPECT_EQ(parent, syscall(__NR_getppid));1468	/* Should also work just fine */1469	EXPECT_EQ(mypid, syscall(__NR_getpid));1470}1471 1472TEST_F(precedence, log_is_fifth_in_any_order)1473{1474	pid_t mypid, parent;1475	long ret;1476 1477	mypid = getpid();1478	parent = getppid();1479	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1480	ASSERT_EQ(0, ret);1481 1482	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);1483	ASSERT_EQ(0, ret);1484	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);1485	ASSERT_EQ(0, ret);1486	/* Should work just fine. */1487	EXPECT_EQ(parent, syscall(__NR_getppid));1488	/* Should also work just fine */1489	EXPECT_EQ(mypid, syscall(__NR_getpid));1490}1491 1492#ifndef PTRACE_O_TRACESECCOMP1493#define PTRACE_O_TRACESECCOMP	0x000000801494#endif1495 1496/* Catch the Ubuntu 12.04 value error. */1497#if PTRACE_EVENT_SECCOMP != 71498#undef PTRACE_EVENT_SECCOMP1499#endif1500 1501#ifndef PTRACE_EVENT_SECCOMP1502#define PTRACE_EVENT_SECCOMP 71503#endif1504 1505#define PTRACE_EVENT_MASK(status) ((status) >> 16)1506bool tracer_running;1507void tracer_stop(int sig)1508{1509	tracer_running = false;1510}1511 1512typedef void tracer_func_t(struct __test_metadata *_metadata,1513			   pid_t tracee, int status, void *args);1514 1515void start_tracer(struct __test_metadata *_metadata, int fd, pid_t tracee,1516	    tracer_func_t tracer_func, void *args, bool ptrace_syscall)1517{1518	int ret = -1;1519	struct sigaction action = {1520		.sa_handler = tracer_stop,1521	};1522 1523	/* Allow external shutdown. */1524	tracer_running = true;1525	ASSERT_EQ(0, sigaction(SIGUSR1, &action, NULL));1526 1527	errno = 0;1528	while (ret == -1 && errno != EINVAL)1529		ret = ptrace(PTRACE_ATTACH, tracee, NULL, 0);1530	ASSERT_EQ(0, ret) {1531		kill(tracee, SIGKILL);1532	}1533	/* Wait for attach stop */1534	wait(NULL);1535 1536	ret = ptrace(PTRACE_SETOPTIONS, tracee, NULL, ptrace_syscall ?1537						      PTRACE_O_TRACESYSGOOD :1538						      PTRACE_O_TRACESECCOMP);1539	ASSERT_EQ(0, ret) {1540		TH_LOG("Failed to set PTRACE_O_TRACESECCOMP");1541		kill(tracee, SIGKILL);1542	}1543	ret = ptrace(ptrace_syscall ? PTRACE_SYSCALL : PTRACE_CONT,1544		     tracee, NULL, 0);1545	ASSERT_EQ(0, ret);1546 1547	/* Unblock the tracee */1548	ASSERT_EQ(1, write(fd, "A", 1));1549	ASSERT_EQ(0, close(fd));1550 1551	/* Run until we're shut down. Must assert to stop execution. */1552	while (tracer_running) {1553		int status;1554 1555		if (wait(&status) != tracee)1556			continue;1557 1558		if (WIFSIGNALED(status)) {1559			/* Child caught a fatal signal. */1560			return;1561		}1562		if (WIFEXITED(status)) {1563			/* Child exited with code. */1564			return;1565		}1566 1567		/* Check if we got an expected event. */1568		ASSERT_EQ(WIFCONTINUED(status), false);1569		ASSERT_EQ(WIFSTOPPED(status), true);1570		ASSERT_EQ(WSTOPSIG(status) & SIGTRAP, SIGTRAP) {1571			TH_LOG("Unexpected WSTOPSIG: %d", WSTOPSIG(status));1572		}1573 1574		tracer_func(_metadata, tracee, status, args);1575 1576		ret = ptrace(ptrace_syscall ? PTRACE_SYSCALL : PTRACE_CONT,1577			     tracee, NULL, 0);1578		ASSERT_EQ(0, ret);1579	}1580	/* Directly report the status of our test harness results. */1581	syscall(__NR_exit, _metadata->exit_code);1582}1583 1584/* Common tracer setup/teardown functions. */1585void cont_handler(int num)1586{ }1587pid_t setup_trace_fixture(struct __test_metadata *_metadata,1588			  tracer_func_t func, void *args, bool ptrace_syscall)1589{1590	char sync;1591	int pipefd[2];1592	pid_t tracer_pid;1593	pid_t tracee = getpid();1594 1595	/* Setup a pipe for clean synchronization. */1596	ASSERT_EQ(0, pipe(pipefd));1597 1598	/* Fork a child which we'll promote to tracer */1599	tracer_pid = fork();1600	ASSERT_LE(0, tracer_pid);1601	signal(SIGALRM, cont_handler);1602	if (tracer_pid == 0) {1603		close(pipefd[0]);1604		start_tracer(_metadata, pipefd[1], tracee, func, args,1605			     ptrace_syscall);1606		syscall(__NR_exit, 0);1607	}1608	close(pipefd[1]);1609	prctl(PR_SET_PTRACER, tracer_pid, 0, 0, 0);1610	read(pipefd[0], &sync, 1);1611	close(pipefd[0]);1612 1613	return tracer_pid;1614}1615 1616void teardown_trace_fixture(struct __test_metadata *_metadata,1617			    pid_t tracer)1618{1619	if (tracer) {1620		int status;1621		/*1622		 * Extract the exit code from the other process and1623		 * adopt it for ourselves in case its asserts failed.1624		 */1625		ASSERT_EQ(0, kill(tracer, SIGUSR1));1626		ASSERT_EQ(tracer, waitpid(tracer, &status, 0));1627		if (WEXITSTATUS(status))1628			_metadata->exit_code = KSFT_FAIL;1629	}1630}1631 1632/* "poke" tracer arguments and function. */1633struct tracer_args_poke_t {1634	unsigned long poke_addr;1635};1636 1637void tracer_poke(struct __test_metadata *_metadata, pid_t tracee, int status,1638		 void *args)1639{1640	int ret;1641	unsigned long msg;1642	struct tracer_args_poke_t *info = (struct tracer_args_poke_t *)args;1643 1644	ret = ptrace(PTRACE_GETEVENTMSG, tracee, NULL, &msg);1645	EXPECT_EQ(0, ret);1646	/* If this fails, don't try to recover. */1647	ASSERT_EQ(0x1001, msg) {1648		kill(tracee, SIGKILL);1649	}1650	/*1651	 * Poke in the message.1652	 * Registers are not touched to try to keep this relatively arch1653	 * agnostic.1654	 */1655	ret = ptrace(PTRACE_POKEDATA, tracee, info->poke_addr, 0x1001);1656	EXPECT_EQ(0, ret);1657}1658 1659FIXTURE(TRACE_poke) {1660	struct sock_fprog prog;1661	pid_t tracer;1662	long poked;1663	struct tracer_args_poke_t tracer_args;1664};1665 1666FIXTURE_SETUP(TRACE_poke)1667{1668	struct sock_filter filter[] = {1669		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,1670			offsetof(struct seccomp_data, nr)),1671		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 0, 1),1672		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE | 0x1001),1673		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),1674	};1675 1676	self->poked = 0;1677	memset(&self->prog, 0, sizeof(self->prog));1678	self->prog.filter = malloc(sizeof(filter));1679	ASSERT_NE(NULL, self->prog.filter);1680	memcpy(self->prog.filter, filter, sizeof(filter));1681	self->prog.len = (unsigned short)ARRAY_SIZE(filter);1682 1683	/* Set up tracer args. */1684	self->tracer_args.poke_addr = (unsigned long)&self->poked;1685 1686	/* Launch tracer. */1687	self->tracer = setup_trace_fixture(_metadata, tracer_poke,1688					   &self->tracer_args, false);1689}1690 1691FIXTURE_TEARDOWN(TRACE_poke)1692{1693	teardown_trace_fixture(_metadata, self->tracer);1694	if (self->prog.filter)1695		free(self->prog.filter);1696}1697 1698TEST_F(TRACE_poke, read_has_side_effects)1699{1700	ssize_t ret;1701 1702	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1703	ASSERT_EQ(0, ret);1704 1705	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);1706	ASSERT_EQ(0, ret);1707 1708	EXPECT_EQ(0, self->poked);1709	ret = read(-1, NULL, 0);1710	EXPECT_EQ(-1, ret);1711	EXPECT_EQ(0x1001, self->poked);1712}1713 1714TEST_F(TRACE_poke, getpid_runs_normally)1715{1716	long ret;1717 1718	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);1719	ASSERT_EQ(0, ret);1720 1721	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);1722	ASSERT_EQ(0, ret);1723 1724	EXPECT_EQ(0, self->poked);1725	EXPECT_NE(0, syscall(__NR_getpid));1726	EXPECT_EQ(0, self->poked);1727}1728 1729#if defined(__x86_64__)1730# define ARCH_REGS		struct user_regs_struct1731# define SYSCALL_NUM(_regs)	(_regs).orig_rax1732# define SYSCALL_RET(_regs)	(_regs).rax1733#elif defined(__i386__)1734# define ARCH_REGS		struct user_regs_struct1735# define SYSCALL_NUM(_regs)	(_regs).orig_eax1736# define SYSCALL_RET(_regs)	(_regs).eax1737#elif defined(__arm__)1738# define ARCH_REGS		struct pt_regs1739# define SYSCALL_NUM(_regs)	(_regs).ARM_r71740# ifndef PTRACE_SET_SYSCALL1741#  define PTRACE_SET_SYSCALL   231742# endif1743# define SYSCALL_NUM_SET(_regs, _nr)	\1744		EXPECT_EQ(0, ptrace(PTRACE_SET_SYSCALL, tracee, NULL, _nr))1745# define SYSCALL_RET(_regs)	(_regs).ARM_r01746#elif defined(__aarch64__)1747# define ARCH_REGS		struct user_pt_regs1748# define SYSCALL_NUM(_regs)	(_regs).regs[8]1749# ifndef NT_ARM_SYSTEM_CALL1750#  define NT_ARM_SYSTEM_CALL 0x4041751# endif1752# define SYSCALL_NUM_SET(_regs, _nr)				\1753	do {							\1754		struct iovec __v;				\1755		typeof(_nr) __nr = (_nr);			\1756		__v.iov_base = &__nr;				\1757		__v.iov_len = sizeof(__nr);			\1758		EXPECT_EQ(0, ptrace(PTRACE_SETREGSET, tracee,	\1759				    NT_ARM_SYSTEM_CALL, &__v));	\1760	} while (0)1761# define SYSCALL_RET(_regs)	(_regs).regs[0]1762#elif defined(__loongarch__)1763# define ARCH_REGS		struct user_pt_regs1764# define SYSCALL_NUM(_regs)	(_regs).regs[11]1765# define SYSCALL_RET(_regs)	(_regs).regs[4]1766#elif defined(__riscv) && __riscv_xlen == 641767# define ARCH_REGS		struct user_regs_struct1768# define SYSCALL_NUM(_regs)	(_regs).a71769# define SYSCALL_RET(_regs)	(_regs).a01770#elif defined(__csky__)1771# define ARCH_REGS		struct pt_regs1772#  if defined(__CSKYABIV2__)1773#   define SYSCALL_NUM(_regs)	(_regs).regs[3]1774#  else1775#   define SYSCALL_NUM(_regs)	(_regs).regs[9]1776#  endif1777# define SYSCALL_RET(_regs)	(_regs).a01778#elif defined(__hppa__)1779# define ARCH_REGS		struct user_regs_struct1780# define SYSCALL_NUM(_regs)	(_regs).gr[20]1781# define SYSCALL_RET(_regs)	(_regs).gr[28]1782#elif defined(__powerpc__)1783# define ARCH_REGS		struct pt_regs1784# define SYSCALL_NUM(_regs)	(_regs).gpr[0]1785# define SYSCALL_RET(_regs)	(_regs).gpr[3]1786# define SYSCALL_RET_SET(_regs, _val)				\1787	do {							\1788		typeof(_val) _result = (_val);			\1789		if ((_regs.trap & 0xfff0) == 0x3000) {		\1790			/*					\1791			 * scv 0 system call uses -ve result	\1792			 * for error, so no need to adjust.	\1793			 */					\1794			SYSCALL_RET(_regs) = _result;		\1795		} else {					\1796			/*					\1797			 * A syscall error is signaled by the	\1798			 * CR0 SO bit and the code is stored as	\1799			 * a positive value.			\1800			 */					\1801			if (_result < 0) {			\1802				SYSCALL_RET(_regs) = -_result;	\1803				(_regs).ccr |= 0x10000000;	\1804			} else {				\1805				SYSCALL_RET(_regs) = _result;	\1806				(_regs).ccr &= ~0x10000000;	\1807			}					\1808		}						\1809	} while (0)1810# define SYSCALL_RET_SET_ON_PTRACE_EXIT1811#elif defined(__s390__)1812# define ARCH_REGS		s390_regs1813# define SYSCALL_NUM(_regs)	(_regs).gprs[2]1814# define SYSCALL_RET_SET(_regs, _val)			\1815		TH_LOG("Can't modify syscall return on this architecture")1816#elif defined(__mips__)1817# include <asm/unistd_nr_n32.h>1818# include <asm/unistd_nr_n64.h>1819# include <asm/unistd_nr_o32.h>1820# define ARCH_REGS		struct pt_regs1821# define SYSCALL_NUM(_regs)				\1822	({						\1823		typeof((_regs).regs[2]) _nr;		\1824		if ((_regs).regs[2] == __NR_O32_Linux)	\1825			_nr = (_regs).regs[4];		\1826		else					\1827			_nr = (_regs).regs[2];		\1828		_nr;					\1829	})1830# define SYSCALL_NUM_SET(_regs, _nr)			\1831	do {						\1832		if ((_regs).regs[2] == __NR_O32_Linux)	\1833			(_regs).regs[4] = _nr;		\1834		else					\1835			(_regs).regs[2] = _nr;		\1836	} while (0)1837# define SYSCALL_RET_SET(_regs, _val)			\1838		TH_LOG("Can't modify syscall return on this architecture")1839#elif defined(__xtensa__)1840# define ARCH_REGS		struct user_pt_regs1841# define SYSCALL_NUM(_regs)	(_regs).syscall1842/*1843 * On xtensa syscall return value is in the register1844 * a2 of the current window which is not fixed.1845 */1846#define SYSCALL_RET(_regs)	(_regs).a[(_regs).windowbase * 4 + 2]1847#elif defined(__sh__)1848# define ARCH_REGS		struct pt_regs1849# define SYSCALL_NUM(_regs)	(_regs).regs[3]1850# define SYSCALL_RET(_regs)	(_regs).regs[0]1851#elif defined(__mc68000__)1852# define ARCH_REGS		struct user_regs_struct1853# define SYSCALL_NUM(_regs)	(_regs).orig_d01854# define SYSCALL_RET(_regs)	(_regs).d01855#else1856# error "Do not know how to find your architecture's registers and syscalls"1857#endif1858 1859/*1860 * Most architectures can change the syscall by just updating the1861 * associated register. This is the default if not defined above.1862 */1863#ifndef SYSCALL_NUM_SET1864# define SYSCALL_NUM_SET(_regs, _nr)		\1865	do {					\1866		SYSCALL_NUM(_regs) = (_nr);	\1867	} while (0)1868#endif1869/*1870 * Most architectures can change the syscall return value by just1871 * writing to the SYSCALL_RET register. This is the default if not1872 * defined above. If an architecture cannot set the return value1873 * (for example when the syscall and return value register is1874 * shared), report it with TH_LOG() in an arch-specific definition1875 * of SYSCALL_RET_SET() above, and leave SYSCALL_RET undefined.1876 */1877#if !defined(SYSCALL_RET) && !defined(SYSCALL_RET_SET)1878# error "One of SYSCALL_RET or SYSCALL_RET_SET is needed for this arch"1879#endif1880#ifndef SYSCALL_RET_SET1881# define SYSCALL_RET_SET(_regs, _val)		\1882	do {					\1883		SYSCALL_RET(_regs) = (_val);	\1884	} while (0)1885#endif1886 1887/* When the syscall return can't be changed, stub out the tests for it. */1888#ifndef SYSCALL_RET1889# define EXPECT_SYSCALL_RETURN(val, action)	EXPECT_EQ(-1, action)1890#else1891# define EXPECT_SYSCALL_RETURN(val, action)		\1892	do {						\1893		errno = 0;				\1894		if (val < 0) {				\1895			EXPECT_EQ(-1, action);		\1896			EXPECT_EQ(-(val), errno);	\1897		} else {				\1898			EXPECT_EQ(val, action);		\1899		}					\1900	} while (0)1901#endif1902 1903/*1904 * Some architectures (e.g. powerpc) can only set syscall1905 * return values on syscall exit during ptrace.1906 */1907const bool ptrace_entry_set_syscall_nr = true;1908const bool ptrace_entry_set_syscall_ret =1909#ifndef SYSCALL_RET_SET_ON_PTRACE_EXIT1910	true;1911#else1912	false;1913#endif1914 1915/*1916 * Use PTRACE_GETREGS and PTRACE_SETREGS when available. This is useful for1917 * architectures without HAVE_ARCH_TRACEHOOK (e.g. User-mode Linux).1918 */1919#if defined(__x86_64__) || defined(__i386__) || defined(__mips__) || defined(__mc68000__)1920# define ARCH_GETREGS(_regs)	ptrace(PTRACE_GETREGS, tracee, 0, &(_regs))1921# define ARCH_SETREGS(_regs)	ptrace(PTRACE_SETREGS, tracee, 0, &(_regs))1922#else1923# define ARCH_GETREGS(_regs)	({					\1924		struct iovec __v;					\1925		__v.iov_base = &(_regs);				\1926		__v.iov_len = sizeof(_regs);				\1927		ptrace(PTRACE_GETREGSET, tracee, NT_PRSTATUS, &__v);	\1928	})1929# define ARCH_SETREGS(_regs)	({					\1930		struct iovec __v;					\1931		__v.iov_base = &(_regs);				\1932		__v.iov_len = sizeof(_regs);				\1933		ptrace(PTRACE_SETREGSET, tracee, NT_PRSTATUS, &__v);	\1934	})1935#endif1936 1937/* Architecture-specific syscall fetching routine. */1938int get_syscall(struct __test_metadata *_metadata, pid_t tracee)1939{1940	ARCH_REGS regs;1941 1942	EXPECT_EQ(0, ARCH_GETREGS(regs)) {1943		return -1;1944	}1945 1946	return SYSCALL_NUM(regs);1947}1948 1949/* Architecture-specific syscall changing routine. */1950void __change_syscall(struct __test_metadata *_metadata,1951		    pid_t tracee, long *syscall, long *ret)1952{1953	ARCH_REGS orig, regs;1954 1955	/* Do not get/set registers if we have nothing to do. */1956	if (!syscall && !ret)1957		return;1958 1959	EXPECT_EQ(0, ARCH_GETREGS(regs)) {1960		return;1961	}1962	orig = regs;1963 1964	if (syscall)1965		SYSCALL_NUM_SET(regs, *syscall);1966 1967	if (ret)1968		SYSCALL_RET_SET(regs, *ret);1969 1970	/* Flush any register changes made. */1971	if (memcmp(&orig, &regs, sizeof(orig)) != 0)1972		EXPECT_EQ(0, ARCH_SETREGS(regs));1973}1974 1975/* Change only syscall number. */1976void change_syscall_nr(struct __test_metadata *_metadata,1977		       pid_t tracee, long syscall)1978{1979	__change_syscall(_metadata, tracee, &syscall, NULL);1980}1981 1982/* Change syscall return value (and set syscall number to -1). */1983void change_syscall_ret(struct __test_metadata *_metadata,1984			pid_t tracee, long ret)1985{1986	long syscall = -1;1987 1988	__change_syscall(_metadata, tracee, &syscall, &ret);1989}1990 1991void tracer_seccomp(struct __test_metadata *_metadata, pid_t tracee,1992		    int status, void *args)1993{1994	int ret;1995	unsigned long msg;1996 1997	EXPECT_EQ(PTRACE_EVENT_MASK(status), PTRACE_EVENT_SECCOMP) {1998		TH_LOG("Unexpected ptrace event: %d", PTRACE_EVENT_MASK(status));1999		return;2000	}2001 2002	/* Make sure we got the right message. */2003	ret = ptrace(PTRACE_GETEVENTMSG, tracee, NULL, &msg);2004	EXPECT_EQ(0, ret);2005 2006	/* Validate and take action on expected syscalls. */2007	switch (msg) {2008	case 0x1002:2009		/* change getpid to getppid. */2010		EXPECT_EQ(__NR_getpid, get_syscall(_metadata, tracee));2011		change_syscall_nr(_metadata, tracee, __NR_getppid);2012		break;2013	case 0x1003:2014		/* skip gettid with valid return code. */2015		EXPECT_EQ(__NR_gettid, get_syscall(_metadata, tracee));2016		change_syscall_ret(_metadata, tracee, 45000);2017		break;2018	case 0x1004:2019		/* skip openat with error. */2020		EXPECT_EQ(__NR_openat, get_syscall(_metadata, tracee));2021		change_syscall_ret(_metadata, tracee, -ESRCH);2022		break;2023	case 0x1005:2024		/* do nothing (allow getppid) */2025		EXPECT_EQ(__NR_getppid, get_syscall(_metadata, tracee));2026		break;2027	default:2028		EXPECT_EQ(0, msg) {2029			TH_LOG("Unknown PTRACE_GETEVENTMSG: 0x%lx", msg);2030			kill(tracee, SIGKILL);2031		}2032	}2033 2034}2035 2036FIXTURE(TRACE_syscall) {2037	struct sock_fprog prog;2038	pid_t tracer, mytid, mypid, parent;2039	long syscall_nr;2040};2041 2042void tracer_ptrace(struct __test_metadata *_metadata, pid_t tracee,2043		   int status, void *args)2044{2045	int ret;2046	unsigned long msg;2047	static bool entry;2048	long syscall_nr_val, syscall_ret_val;2049	long *syscall_nr = NULL, *syscall_ret = NULL;2050	FIXTURE_DATA(TRACE_syscall) *self = args;2051 2052	EXPECT_EQ(WSTOPSIG(status) & 0x80, 0x80) {2053		TH_LOG("Unexpected WSTOPSIG: %d", WSTOPSIG(status));2054		return;2055	}2056 2057	/*2058	 * The traditional way to tell PTRACE_SYSCALL entry/exit2059	 * is by counting.2060	 */2061	entry = !entry;2062 2063	/* Make sure we got an appropriate message. */2064	ret = ptrace(PTRACE_GETEVENTMSG, tracee, NULL, &msg);2065	EXPECT_EQ(0, ret);2066	EXPECT_EQ(entry ? PTRACE_EVENTMSG_SYSCALL_ENTRY2067			: PTRACE_EVENTMSG_SYSCALL_EXIT, msg);2068 2069	/*2070	 * Some architectures only support setting return values during2071	 * syscall exit under ptrace, and on exit the syscall number may2072	 * no longer be available. Therefore, save the initial sycall2073	 * number here, so it can be examined during both entry and exit2074	 * phases.2075	 */2076	if (entry)2077		self->syscall_nr = get_syscall(_metadata, tracee);2078 2079	/*2080	 * Depending on the architecture's syscall setting abilities, we2081	 * pick which things to set during this phase (entry or exit).2082	 */2083	if (entry == ptrace_entry_set_syscall_nr)2084		syscall_nr = &syscall_nr_val;2085	if (entry == ptrace_entry_set_syscall_ret)2086		syscall_ret = &syscall_ret_val;2087 2088	/* Now handle the actual rewriting cases. */2089	switch (self->syscall_nr) {2090	case __NR_getpid:2091		syscall_nr_val = __NR_getppid;2092		/* Never change syscall return for this case. */2093		syscall_ret = NULL;2094		break;2095	case __NR_gettid:2096		syscall_nr_val = -1;2097		syscall_ret_val = 45000;2098		break;2099	case __NR_openat:2100		syscall_nr_val = -1;2101		syscall_ret_val = -ESRCH;2102		break;2103	default:2104		/* Unhandled, do nothing. */2105		return;2106	}2107 2108	__change_syscall(_metadata, tracee, syscall_nr, syscall_ret);2109}2110 2111FIXTURE_VARIANT(TRACE_syscall) {2112	/*2113	 * All of the SECCOMP_RET_TRACE behaviors can be tested with either2114	 * SECCOMP_RET_TRACE+PTRACE_CONT or plain ptrace()+PTRACE_SYSCALL.2115	 * This indicates if we should use SECCOMP_RET_TRACE (false), or2116	 * ptrace (true).2117	 */2118	bool use_ptrace;2119};2120 2121FIXTURE_VARIANT_ADD(TRACE_syscall, ptrace) {2122	.use_ptrace = true,2123};2124 2125FIXTURE_VARIANT_ADD(TRACE_syscall, seccomp) {2126	.use_ptrace = false,2127};2128 2129FIXTURE_SETUP(TRACE_syscall)2130{2131	struct sock_filter filter[] = {2132		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,2133			offsetof(struct seccomp_data, nr)),2134		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 0, 1),2135		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE | 0x1002),2136		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_gettid, 0, 1),2137		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE | 0x1003),2138		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_openat, 0, 1),2139		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE | 0x1004),2140		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getppid, 0, 1),2141		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE | 0x1005),2142		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),2143	};2144	struct sock_fprog prog = {2145		.len = (unsigned short)ARRAY_SIZE(filter),2146		.filter = filter,2147	};2148	long ret;2149 2150	/* Prepare some testable syscall results. */2151	self->mytid = syscall(__NR_gettid);2152	ASSERT_GT(self->mytid, 0);2153	ASSERT_NE(self->mytid, 1) {2154		TH_LOG("Running this test as init is not supported. :)");2155	}2156 2157	self->mypid = getpid();2158	ASSERT_GT(self->mypid, 0);2159	ASSERT_EQ(self->mytid, self->mypid);2160 2161	self->parent = getppid();2162	ASSERT_GT(self->parent, 0);2163	ASSERT_NE(self->parent, self->mypid);2164 2165	/* Launch tracer. */2166	self->tracer = setup_trace_fixture(_metadata,2167					   variant->use_ptrace ? tracer_ptrace2168							       : tracer_seccomp,2169					   self, variant->use_ptrace);2170 2171	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);2172	ASSERT_EQ(0, ret);2173 2174	/* Do not install seccomp rewrite filters, as we'll use ptrace instead. */2175	if (variant->use_ptrace)2176		return;2177 2178	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);2179	ASSERT_EQ(0, ret);2180}2181 2182FIXTURE_TEARDOWN(TRACE_syscall)2183{2184	teardown_trace_fixture(_metadata, self->tracer);2185}2186 2187TEST(negative_ENOSYS)2188{2189#if defined(__arm__)2190	SKIP(return, "arm32 does not support calling syscall -1");2191#endif2192	/*2193	 * There should be no difference between an "internal" skip2194	 * and userspace asking for syscall "-1".2195	 */2196	errno = 0;2197	EXPECT_EQ(-1, syscall(-1));2198	EXPECT_EQ(errno, ENOSYS);2199	/* And no difference for "still not valid but not -1". */2200	errno = 0;2201	EXPECT_EQ(-1, syscall(-101));2202	EXPECT_EQ(errno, ENOSYS);2203}2204 2205TEST_F(TRACE_syscall, negative_ENOSYS)2206{2207	negative_ENOSYS(_metadata);2208}2209 2210TEST_F(TRACE_syscall, syscall_allowed)2211{2212	/* getppid works as expected (no changes). */2213	EXPECT_EQ(self->parent, syscall(__NR_getppid));2214	EXPECT_NE(self->mypid, syscall(__NR_getppid));2215}2216 2217TEST_F(TRACE_syscall, syscall_redirected)2218{2219	/* getpid has been redirected to getppid as expected. */2220	EXPECT_EQ(self->parent, syscall(__NR_getpid));2221	EXPECT_NE(self->mypid, syscall(__NR_getpid));2222}2223 2224TEST_F(TRACE_syscall, syscall_errno)2225{2226	/* Tracer should skip the open syscall, resulting in ESRCH. */2227	EXPECT_SYSCALL_RETURN(-ESRCH, syscall(__NR_openat));2228}2229 2230TEST_F(TRACE_syscall, syscall_faked)2231{2232	/* Tracer skips the gettid syscall and store altered return value. */2233	EXPECT_SYSCALL_RETURN(45000, syscall(__NR_gettid));2234}2235 2236TEST_F_SIGNAL(TRACE_syscall, kill_immediate, SIGSYS)2237{2238	struct sock_filter filter[] = {2239		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,2240			offsetof(struct seccomp_data, nr)),2241		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_mknodat, 0, 1),2242		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL_THREAD),2243		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),2244	};2245	struct sock_fprog prog = {2246		.len = (unsigned short)ARRAY_SIZE(filter),2247		.filter = filter,2248	};2249	long ret;2250 2251	/* Install "kill on mknodat" filter. */2252	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);2253	ASSERT_EQ(0, ret);2254 2255	/* This should immediately die with SIGSYS, regardless of tracer. */2256	EXPECT_EQ(-1, syscall(__NR_mknodat, -1, NULL, 0, 0));2257}2258 2259TEST_F(TRACE_syscall, skip_after)2260{2261	struct sock_filter filter[] = {2262		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,2263			offsetof(struct seccomp_data, nr)),2264		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getppid, 0, 1),2265		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | EPERM),2266		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),2267	};2268	struct sock_fprog prog = {2269		.len = (unsigned short)ARRAY_SIZE(filter),2270		.filter = filter,2271	};2272	long ret;2273 2274	/* Install additional "errno on getppid" filter. */2275	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);2276	ASSERT_EQ(0, ret);2277 2278	/* Tracer will redirect getpid to getppid, and we should see EPERM. */2279	errno = 0;2280	EXPECT_EQ(-1, syscall(__NR_getpid));2281	EXPECT_EQ(EPERM, errno);2282}2283 2284TEST_F_SIGNAL(TRACE_syscall, kill_after, SIGSYS)2285{2286	struct sock_filter filter[] = {2287		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,2288			offsetof(struct seccomp_data, nr)),2289		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getppid, 0, 1),2290		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),2291		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),2292	};2293	struct sock_fprog prog = {2294		.len = (unsigned short)ARRAY_SIZE(filter),2295		.filter = filter,2296	};2297	long ret;2298 2299	/* Install additional "death on getppid" filter. */2300	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);2301	ASSERT_EQ(0, ret);2302 2303	/* Tracer will redirect getpid to getppid, and we should die. */2304	EXPECT_NE(self->mypid, syscall(__NR_getpid));2305}2306 2307TEST(seccomp_syscall)2308{2309	struct sock_filter filter[] = {2310		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),2311	};2312	struct sock_fprog prog = {2313		.len = (unsigned short)ARRAY_SIZE(filter),2314		.filter = filter,2315	};2316	long ret;2317 2318	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);2319	ASSERT_EQ(0, ret) {2320		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");2321	}2322 2323	/* Reject insane operation. */2324	ret = seccomp(-1, 0, &prog);2325	ASSERT_NE(ENOSYS, errno) {2326		TH_LOG("Kernel does not support seccomp syscall!");2327	}2328	EXPECT_EQ(EINVAL, errno) {2329		TH_LOG("Did not reject crazy op value!");2330	}2331 2332	/* Reject strict with flags or pointer. */2333	ret = seccomp(SECCOMP_SET_MODE_STRICT, -1, NULL);2334	EXPECT_EQ(EINVAL, errno) {2335		TH_LOG("Did not reject mode strict with flags!");2336	}2337	ret = seccomp(SECCOMP_SET_MODE_STRICT, 0, &prog);2338	EXPECT_EQ(EINVAL, errno) {2339		TH_LOG("Did not reject mode strict with uargs!");2340	}2341 2342	/* Reject insane args for filter. */2343	ret = seccomp(SECCOMP_SET_MODE_FILTER, -1, &prog);2344	EXPECT_EQ(EINVAL, errno) {2345		TH_LOG("Did not reject crazy filter flags!");2346	}2347	ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, NULL);2348	EXPECT_EQ(EFAULT, errno) {2349		TH_LOG("Did not reject NULL filter!");2350	}2351 2352	ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog);2353	EXPECT_EQ(0, errno) {2354		TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER: %s",2355			strerror(errno));2356	}2357}2358 2359TEST(seccomp_syscall_mode_lock)2360{2361	struct sock_filter filter[] = {2362		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),2363	};2364	struct sock_fprog prog = {2365		.len = (unsigned short)ARRAY_SIZE(filter),2366		.filter = filter,2367	};2368	long ret;2369 2370	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, NULL, 0, 0);2371	ASSERT_EQ(0, ret) {2372		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");2373	}2374 2375	ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog);2376	ASSERT_NE(ENOSYS, errno) {2377		TH_LOG("Kernel does not support seccomp syscall!");2378	}2379	EXPECT_EQ(0, ret) {2380		TH_LOG("Could not install filter!");2381	}2382 2383	/* Make sure neither entry point will switch to strict. */2384	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, 0, 0, 0);2385	EXPECT_EQ(EINVAL, errno) {2386		TH_LOG("Switched to mode strict!");2387	}2388 2389	ret = seccomp(SECCOMP_SET_MODE_STRICT, 0, NULL);2390	EXPECT_EQ(EINVAL, errno) {2391		TH_LOG("Switched to mode strict!");2392	}2393}2394 2395/*2396 * Test detection of known and unknown filter flags. Userspace needs to be able2397 * to check if a filter flag is supported by the current kernel and a good way2398 * of doing that is by attempting to enter filter mode, with the flag bit in2399 * question set, and a NULL pointer for the _args_ parameter. EFAULT indicates2400 * that the flag is valid and EINVAL indicates that the flag is invalid.2401 */2402TEST(detect_seccomp_filter_flags)2403{2404	unsigned int flags[] = { SECCOMP_FILTER_FLAG_TSYNC,2405				 SECCOMP_FILTER_FLAG_LOG,2406				 SECCOMP_FILTER_FLAG_SPEC_ALLOW,2407				 SECCOMP_FILTER_FLAG_NEW_LISTENER,2408				 SECCOMP_FILTER_FLAG_TSYNC_ESRCH };2409	unsigned int exclusive[] = {2410				SECCOMP_FILTER_FLAG_TSYNC,2411				SECCOMP_FILTER_FLAG_NEW_LISTENER };2412	unsigned int flag, all_flags, exclusive_mask;2413	int i;2414	long ret;2415 2416	/* Test detection of individual known-good filter flags */2417	for (i = 0, all_flags = 0; i < ARRAY_SIZE(flags); i++) {2418		int bits = 0;2419 2420		flag = flags[i];2421		/* Make sure the flag is a single bit! */2422		while (flag) {2423			if (flag & 0x1)2424				bits ++;2425			flag >>= 1;2426		}2427		ASSERT_EQ(1, bits);2428		flag = flags[i];2429 2430		ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL);2431		ASSERT_NE(ENOSYS, errno) {2432			TH_LOG("Kernel does not support seccomp syscall!");2433		}2434		EXPECT_EQ(-1, ret);2435		EXPECT_EQ(EFAULT, errno) {2436			TH_LOG("Failed to detect that a known-good filter flag (0x%X) is supported!",2437			       flag);2438		}2439 2440		all_flags |= flag;2441	}2442 2443	/*2444	 * Test detection of all known-good filter flags combined. But2445	 * for the exclusive flags we need to mask them out and try them2446	 * individually for the "all flags" testing.2447	 */2448	exclusive_mask = 0;2449	for (i = 0; i < ARRAY_SIZE(exclusive); i++)2450		exclusive_mask |= exclusive[i];2451	for (i = 0; i < ARRAY_SIZE(exclusive); i++) {2452		flag = all_flags & ~exclusive_mask;2453		flag |= exclusive[i];2454 2455		ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL);2456		EXPECT_EQ(-1, ret);2457		EXPECT_EQ(EFAULT, errno) {2458			TH_LOG("Failed to detect that all known-good filter flags (0x%X) are supported!",2459			       flag);2460		}2461	}2462 2463	/* Test detection of an unknown filter flags, without exclusives. */2464	flag = -1;2465	flag &= ~exclusive_mask;2466	ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL);2467	EXPECT_EQ(-1, ret);2468	EXPECT_EQ(EINVAL, errno) {2469		TH_LOG("Failed to detect that an unknown filter flag (0x%X) is unsupported!",2470		       flag);2471	}2472 2473	/*2474	 * Test detection of an unknown filter flag that may simply need to be2475	 * added to this test2476	 */2477	flag = flags[ARRAY_SIZE(flags) - 1] << 1;2478	ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL);2479	EXPECT_EQ(-1, ret);2480	EXPECT_EQ(EINVAL, errno) {2481		TH_LOG("Failed to detect that an unknown filter flag (0x%X) is unsupported! Does a new flag need to be added to this test?",2482		       flag);2483	}2484}2485 2486TEST(TSYNC_first)2487{2488	struct sock_filter filter[] = {2489		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),2490	};2491	struct sock_fprog prog = {2492		.len = (unsigned short)ARRAY_SIZE(filter),2493		.filter = filter,2494	};2495	long ret;2496 2497	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, NULL, 0, 0);2498	ASSERT_EQ(0, ret) {2499		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");2500	}2501 2502	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC,2503		      &prog);2504	ASSERT_NE(ENOSYS, errno) {2505		TH_LOG("Kernel does not support seccomp syscall!");2506	}2507	EXPECT_EQ(0, ret) {2508		TH_LOG("Could not install initial filter with TSYNC!");2509	}2510}2511 2512#define TSYNC_SIBLINGS 22513struct tsync_sibling {2514	pthread_t tid;2515	pid_t system_tid;2516	sem_t *started;2517	pthread_cond_t *cond;2518	pthread_mutex_t *mutex;2519	int diverge;2520	int num_waits;2521	struct sock_fprog *prog;2522	struct __test_metadata *metadata;2523};2524 2525/*2526 * To avoid joining joined threads (which is not allowed by Bionic),2527 * make sure we both successfully join and clear the tid to skip a2528 * later join attempt during fixture teardown. Any remaining threads2529 * will be directly killed during teardown.2530 */2531#define PTHREAD_JOIN(tid, status)					\2532	do {								\2533		int _rc = pthread_join(tid, status);			\2534		if (_rc) {						\2535			TH_LOG("pthread_join of tid %u failed: %d\n",	\2536				(unsigned int)tid, _rc);		\2537		} else {						\2538			tid = 0;					\2539		}							\2540	} while (0)2541 2542FIXTURE(TSYNC) {2543	struct sock_fprog root_prog, apply_prog;2544	struct tsync_sibling sibling[TSYNC_SIBLINGS];2545	sem_t started;2546	pthread_cond_t cond;2547	pthread_mutex_t mutex;2548	int sibling_count;2549};2550 2551FIXTURE_SETUP(TSYNC)2552{2553	struct sock_filter root_filter[] = {2554		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),2555	};2556	struct sock_filter apply_filter[] = {2557		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,2558			offsetof(struct seccomp_data, nr)),2559		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 0, 1),2560		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),2561		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),2562	};2563 2564	memset(&self->root_prog, 0, sizeof(self->root_prog));2565	memset(&self->apply_prog, 0, sizeof(self->apply_prog));2566	memset(&self->sibling, 0, sizeof(self->sibling));2567	self->root_prog.filter = malloc(sizeof(root_filter));2568	ASSERT_NE(NULL, self->root_prog.filter);2569	memcpy(self->root_prog.filter, &root_filter, sizeof(root_filter));2570	self->root_prog.len = (unsigned short)ARRAY_SIZE(root_filter);2571 2572	self->apply_prog.filter = malloc(sizeof(apply_filter));2573	ASSERT_NE(NULL, self->apply_prog.filter);2574	memcpy(self->apply_prog.filter, &apply_filter, sizeof(apply_filter));2575	self->apply_prog.len = (unsigned short)ARRAY_SIZE(apply_filter);2576 2577	self->sibling_count = 0;2578	pthread_mutex_init(&self->mutex, NULL);2579	pthread_cond_init(&self->cond, NULL);2580	sem_init(&self->started, 0, 0);2581	self->sibling[0].tid = 0;2582	self->sibling[0].cond = &self->cond;2583	self->sibling[0].started = &self->started;2584	self->sibling[0].mutex = &self->mutex;2585	self->sibling[0].diverge = 0;2586	self->sibling[0].num_waits = 1;2587	self->sibling[0].prog = &self->root_prog;2588	self->sibling[0].metadata = _metadata;2589	self->sibling[1].tid = 0;2590	self->sibling[1].cond = &self->cond;2591	self->sibling[1].started = &self->started;2592	self->sibling[1].mutex = &self->mutex;2593	self->sibling[1].diverge = 0;2594	self->sibling[1].prog = &self->root_prog;2595	self->sibling[1].num_waits = 1;2596	self->sibling[1].metadata = _metadata;2597}2598 2599FIXTURE_TEARDOWN(TSYNC)2600{2601	int sib = 0;2602 2603	if (self->root_prog.filter)2604		free(self->root_prog.filter);2605	if (self->apply_prog.filter)2606		free(self->apply_prog.filter);2607 2608	for ( ; sib < self->sibling_count; ++sib) {2609		struct tsync_sibling *s = &self->sibling[sib];2610 2611		if (!s->tid)2612			continue;2613		/*2614		 * If a thread is still running, it may be stuck, so hit2615		 * it over the head really hard.2616		 */2617		pthread_kill(s->tid, 9);2618	}2619	pthread_mutex_destroy(&self->mutex);2620	pthread_cond_destroy(&self->cond);2621	sem_destroy(&self->started);2622}2623 2624void *tsync_sibling(void *data)2625{2626	long ret = 0;2627	struct tsync_sibling *me = data;2628 2629	me->system_tid = syscall(__NR_gettid);2630 2631	pthread_mutex_lock(me->mutex);2632	if (me->diverge) {2633		/* Just re-apply the root prog to fork the tree */2634		ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER,2635				me->prog, 0, 0);2636	}2637	sem_post(me->started);2638	/* Return outside of started so parent notices failures. */2639	if (ret) {2640		pthread_mutex_unlock(me->mutex);2641		return (void *)SIBLING_EXIT_FAILURE;2642	}2643	do {2644		pthread_cond_wait(me->cond, me->mutex);2645		me->num_waits = me->num_waits - 1;2646	} while (me->num_waits);2647	pthread_mutex_unlock(me->mutex);2648 2649	ret = prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0);2650	if (!ret)2651		return (void *)SIBLING_EXIT_NEWPRIVS;2652	read(-1, NULL, 0);2653	return (void *)SIBLING_EXIT_UNKILLED;2654}2655 2656void tsync_start_sibling(struct tsync_sibling *sibling)2657{2658	pthread_create(&sibling->tid, NULL, tsync_sibling, (void *)sibling);2659}2660 2661TEST_F(TSYNC, siblings_fail_prctl)2662{2663	long ret;2664	void *status;2665	struct sock_filter filter[] = {2666		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,2667			offsetof(struct seccomp_data, nr)),2668		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_prctl, 0, 1),2669		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | EINVAL),2670		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),2671	};2672	struct sock_fprog prog = {2673		.len = (unsigned short)ARRAY_SIZE(filter),2674		.filter = filter,2675	};2676 2677	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {2678		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");2679	}2680 2681	/* Check prctl failure detection by requesting sib 0 diverge. */2682	ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog);2683	ASSERT_NE(ENOSYS, errno) {2684		TH_LOG("Kernel does not support seccomp syscall!");2685	}2686	ASSERT_EQ(0, ret) {2687		TH_LOG("setting filter failed");2688	}2689 2690	self->sibling[0].diverge = 1;2691	tsync_start_sibling(&self->sibling[0]);2692	tsync_start_sibling(&self->sibling[1]);2693 2694	while (self->sibling_count < TSYNC_SIBLINGS) {2695		sem_wait(&self->started);2696		self->sibling_count++;2697	}2698 2699	/* Signal the threads to clean up*/2700	pthread_mutex_lock(&self->mutex);2701	ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {2702		TH_LOG("cond broadcast non-zero");2703	}2704	pthread_mutex_unlock(&self->mutex);2705 2706	/* Ensure diverging sibling failed to call prctl. */2707	PTHREAD_JOIN(self->sibling[0].tid, &status);2708	EXPECT_EQ(SIBLING_EXIT_FAILURE, (long)status);2709	PTHREAD_JOIN(self->sibling[1].tid, &status);2710	EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);2711}2712 2713TEST_F(TSYNC, two_siblings_with_ancestor)2714{2715	long ret;2716	void *status;2717 2718	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {2719		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");2720	}2721 2722	ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &self->root_prog);2723	ASSERT_NE(ENOSYS, errno) {2724		TH_LOG("Kernel does not support seccomp syscall!");2725	}2726	ASSERT_EQ(0, ret) {2727		TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER!");2728	}2729	tsync_start_sibling(&self->sibling[0]);2730	tsync_start_sibling(&self->sibling[1]);2731 2732	while (self->sibling_count < TSYNC_SIBLINGS) {2733		sem_wait(&self->started);2734		self->sibling_count++;2735	}2736 2737	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC,2738		      &self->apply_prog);2739	ASSERT_EQ(0, ret) {2740		TH_LOG("Could install filter on all threads!");2741	}2742	/* Tell the siblings to test the policy */2743	pthread_mutex_lock(&self->mutex);2744	ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {2745		TH_LOG("cond broadcast non-zero");2746	}2747	pthread_mutex_unlock(&self->mutex);2748	/* Ensure they are both killed and don't exit cleanly. */2749	PTHREAD_JOIN(self->sibling[0].tid, &status);2750	EXPECT_EQ(0x0, (long)status);2751	PTHREAD_JOIN(self->sibling[1].tid, &status);2752	EXPECT_EQ(0x0, (long)status);2753}2754 2755TEST_F(TSYNC, two_sibling_want_nnp)2756{2757	void *status;2758 2759	/* start siblings before any prctl() operations */2760	tsync_start_sibling(&self->sibling[0]);2761	tsync_start_sibling(&self->sibling[1]);2762	while (self->sibling_count < TSYNC_SIBLINGS) {2763		sem_wait(&self->started);2764		self->sibling_count++;2765	}2766 2767	/* Tell the siblings to test no policy */2768	pthread_mutex_lock(&self->mutex);2769	ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {2770		TH_LOG("cond broadcast non-zero");2771	}2772	pthread_mutex_unlock(&self->mutex);2773 2774	/* Ensure they are both upset about lacking nnp. */2775	PTHREAD_JOIN(self->sibling[0].tid, &status);2776	EXPECT_EQ(SIBLING_EXIT_NEWPRIVS, (long)status);2777	PTHREAD_JOIN(self->sibling[1].tid, &status);2778	EXPECT_EQ(SIBLING_EXIT_NEWPRIVS, (long)status);2779}2780 2781TEST_F(TSYNC, two_siblings_with_no_filter)2782{2783	long ret;2784	void *status;2785 2786	/* start siblings before any prctl() operations */2787	tsync_start_sibling(&self->sibling[0]);2788	tsync_start_sibling(&self->sibling[1]);2789	while (self->sibling_count < TSYNC_SIBLINGS) {2790		sem_wait(&self->started);2791		self->sibling_count++;2792	}2793 2794	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {2795		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");2796	}2797 2798	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC,2799		      &self->apply_prog);2800	ASSERT_NE(ENOSYS, errno) {2801		TH_LOG("Kernel does not support seccomp syscall!");2802	}2803	ASSERT_EQ(0, ret) {2804		TH_LOG("Could install filter on all threads!");2805	}2806 2807	/* Tell the siblings to test the policy */2808	pthread_mutex_lock(&self->mutex);2809	ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {2810		TH_LOG("cond broadcast non-zero");2811	}2812	pthread_mutex_unlock(&self->mutex);2813 2814	/* Ensure they are both killed and don't exit cleanly. */2815	PTHREAD_JOIN(self->sibling[0].tid, &status);2816	EXPECT_EQ(0x0, (long)status);2817	PTHREAD_JOIN(self->sibling[1].tid, &status);2818	EXPECT_EQ(0x0, (long)status);2819}2820 2821TEST_F(TSYNC, two_siblings_with_one_divergence)2822{2823	long ret;2824	void *status;2825 2826	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {2827		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");2828	}2829 2830	ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &self->root_prog);2831	ASSERT_NE(ENOSYS, errno) {2832		TH_LOG("Kernel does not support seccomp syscall!");2833	}2834	ASSERT_EQ(0, ret) {2835		TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER!");2836	}2837	self->sibling[0].diverge = 1;2838	tsync_start_sibling(&self->sibling[0]);2839	tsync_start_sibling(&self->sibling[1]);2840 2841	while (self->sibling_count < TSYNC_SIBLINGS) {2842		sem_wait(&self->started);2843		self->sibling_count++;2844	}2845 2846	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC,2847		      &self->apply_prog);2848	ASSERT_EQ(self->sibling[0].system_tid, ret) {2849		TH_LOG("Did not fail on diverged sibling.");2850	}2851 2852	/* Wake the threads */2853	pthread_mutex_lock(&self->mutex);2854	ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {2855		TH_LOG("cond broadcast non-zero");2856	}2857	pthread_mutex_unlock(&self->mutex);2858 2859	/* Ensure they are both unkilled. */2860	PTHREAD_JOIN(self->sibling[0].tid, &status);2861	EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);2862	PTHREAD_JOIN(self->sibling[1].tid, &status);2863	EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);2864}2865 2866TEST_F(TSYNC, two_siblings_with_one_divergence_no_tid_in_err)2867{2868	long ret, flags;2869	void *status;2870 2871	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {2872		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");2873	}2874 2875	ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &self->root_prog);2876	ASSERT_NE(ENOSYS, errno) {2877		TH_LOG("Kernel does not support seccomp syscall!");2878	}2879	ASSERT_EQ(0, ret) {2880		TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER!");2881	}2882	self->sibling[0].diverge = 1;2883	tsync_start_sibling(&self->sibling[0]);2884	tsync_start_sibling(&self->sibling[1]);2885 2886	while (self->sibling_count < TSYNC_SIBLINGS) {2887		sem_wait(&self->started);2888		self->sibling_count++;2889	}2890 2891	flags = SECCOMP_FILTER_FLAG_TSYNC | \2892		SECCOMP_FILTER_FLAG_TSYNC_ESRCH;2893	ret = seccomp(SECCOMP_SET_MODE_FILTER, flags, &self->apply_prog);2894	ASSERT_EQ(ESRCH, errno) {2895		TH_LOG("Did not return ESRCH for diverged sibling.");2896	}2897	ASSERT_EQ(-1, ret) {2898		TH_LOG("Did not fail on diverged sibling.");2899	}2900 2901	/* Wake the threads */2902	pthread_mutex_lock(&self->mutex);2903	ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {2904		TH_LOG("cond broadcast non-zero");2905	}2906	pthread_mutex_unlock(&self->mutex);2907 2908	/* Ensure they are both unkilled. */2909	PTHREAD_JOIN(self->sibling[0].tid, &status);2910	EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);2911	PTHREAD_JOIN(self->sibling[1].tid, &status);2912	EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);2913}2914 2915TEST_F(TSYNC, two_siblings_not_under_filter)2916{2917	long ret, sib;2918	void *status;2919	struct timespec delay = { .tv_nsec = 100000000 };2920 2921	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {2922		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");2923	}2924 2925	/*2926	 * Sibling 0 will have its own seccomp policy2927	 * and Sibling 1 will not be under seccomp at2928	 * all. Sibling 1 will enter seccomp and 02929	 * will cause failure.2930	 */2931	self->sibling[0].diverge = 1;2932	tsync_start_sibling(&self->sibling[0]);2933	tsync_start_sibling(&self->sibling[1]);2934 2935	while (self->sibling_count < TSYNC_SIBLINGS) {2936		sem_wait(&self->started);2937		self->sibling_count++;2938	}2939 2940	ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &self->root_prog);2941	ASSERT_NE(ENOSYS, errno) {2942		TH_LOG("Kernel does not support seccomp syscall!");2943	}2944	ASSERT_EQ(0, ret) {2945		TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER!");2946	}2947 2948	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC,2949		      &self->apply_prog);2950	ASSERT_EQ(ret, self->sibling[0].system_tid) {2951		TH_LOG("Did not fail on diverged sibling.");2952	}2953	sib = 1;2954	if (ret == self->sibling[0].system_tid)2955		sib = 0;2956 2957	pthread_mutex_lock(&self->mutex);2958 2959	/* Increment the other siblings num_waits so we can clean up2960	 * the one we just saw.2961	 */2962	self->sibling[!sib].num_waits += 1;2963 2964	/* Signal the thread to clean up*/2965	ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {2966		TH_LOG("cond broadcast non-zero");2967	}2968	pthread_mutex_unlock(&self->mutex);2969	PTHREAD_JOIN(self->sibling[sib].tid, &status);2970	EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);2971	/* Poll for actual task death. pthread_join doesn't guarantee it. */2972	while (!kill(self->sibling[sib].system_tid, 0))2973		nanosleep(&delay, NULL);2974	/* Switch to the remaining sibling */2975	sib = !sib;2976 2977	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC,2978		      &self->apply_prog);2979	ASSERT_EQ(0, ret) {2980		TH_LOG("Expected the remaining sibling to sync");2981	};2982 2983	pthread_mutex_lock(&self->mutex);2984 2985	/* If remaining sibling didn't have a chance to wake up during2986	 * the first broadcast, manually reduce the num_waits now.2987	 */2988	if (self->sibling[sib].num_waits > 1)2989		self->sibling[sib].num_waits = 1;2990	ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {2991		TH_LOG("cond broadcast non-zero");2992	}2993	pthread_mutex_unlock(&self->mutex);2994	PTHREAD_JOIN(self->sibling[sib].tid, &status);2995	EXPECT_EQ(0, (long)status);2996	/* Poll for actual task death. pthread_join doesn't guarantee it. */2997	while (!kill(self->sibling[sib].system_tid, 0))2998		nanosleep(&delay, NULL);2999 3000	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC,3001		      &self->apply_prog);3002	ASSERT_EQ(0, ret);  /* just us chickens */3003}3004 3005/* Make sure restarted syscalls are seen directly as "restart_syscall". */3006TEST(syscall_restart)3007{3008	long ret;3009	unsigned long msg;3010	pid_t child_pid;3011	int pipefd[2];3012	int status;3013	siginfo_t info = { };3014	struct sock_filter filter[] = {3015		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,3016			 offsetof(struct seccomp_data, nr)),3017 3018#ifdef __NR_sigreturn3019		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_sigreturn, 7, 0),3020#endif3021		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 6, 0),3022		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_exit, 5, 0),3023		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_rt_sigreturn, 4, 0),3024		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_nanosleep, 5, 0),3025		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_clock_nanosleep, 4, 0),3026		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_restart_syscall, 4, 0),3027 3028		/* Allow __NR_write for easy logging. */3029		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_write, 0, 1),3030		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),3031		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),3032		/* The nanosleep jump target. */3033		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x100),3034		/* The restart_syscall jump target. */3035		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x200),3036	};3037	struct sock_fprog prog = {3038		.len = (unsigned short)ARRAY_SIZE(filter),3039		.filter = filter,3040	};3041#if defined(__arm__)3042	struct utsname utsbuf;3043#endif3044 3045	ASSERT_EQ(0, pipe(pipefd));3046 3047	child_pid = fork();3048	ASSERT_LE(0, child_pid);3049	if (child_pid == 0) {3050		/* Child uses EXPECT not ASSERT to deliver status correctly. */3051		char buf = ' ';3052		struct timespec timeout = { };3053 3054		/* Attach parent as tracer and stop. */3055		EXPECT_EQ(0, ptrace(PTRACE_TRACEME));3056		EXPECT_EQ(0, raise(SIGSTOP));3057 3058		EXPECT_EQ(0, close(pipefd[1]));3059 3060		EXPECT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {3061			TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");3062		}3063 3064		ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);3065		EXPECT_EQ(0, ret) {3066			TH_LOG("Failed to install filter!");3067		}3068 3069		EXPECT_EQ(1, read(pipefd[0], &buf, 1)) {3070			TH_LOG("Failed to read() sync from parent");3071		}3072		EXPECT_EQ('.', buf) {3073			TH_LOG("Failed to get sync data from read()");3074		}3075 3076		/* Start nanosleep to be interrupted. */3077		timeout.tv_sec = 1;3078		errno = 0;3079		EXPECT_EQ(0, nanosleep(&timeout, NULL)) {3080			TH_LOG("Call to nanosleep() failed (errno %d: %s)",3081				errno, strerror(errno));3082		}3083 3084		/* Read final sync from parent. */3085		EXPECT_EQ(1, read(pipefd[0], &buf, 1)) {3086			TH_LOG("Failed final read() from parent");3087		}3088		EXPECT_EQ('!', buf) {3089			TH_LOG("Failed to get final data from read()");3090		}3091 3092		/* Directly report the status of our test harness results. */3093		syscall(__NR_exit, _metadata->exit_code);3094	}3095	EXPECT_EQ(0, close(pipefd[0]));3096 3097	/* Attach to child, setup options, and release. */3098	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));3099	ASSERT_EQ(true, WIFSTOPPED(status));3100	ASSERT_EQ(0, ptrace(PTRACE_SETOPTIONS, child_pid, NULL,3101			    PTRACE_O_TRACESECCOMP));3102	ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));3103	ASSERT_EQ(1, write(pipefd[1], ".", 1));3104 3105	/* Wait for nanosleep() to start. */3106	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));3107	ASSERT_EQ(true, WIFSTOPPED(status));3108	ASSERT_EQ(SIGTRAP, WSTOPSIG(status));3109	ASSERT_EQ(PTRACE_EVENT_SECCOMP, (status >> 16));3110	ASSERT_EQ(0, ptrace(PTRACE_GETEVENTMSG, child_pid, NULL, &msg));3111	ASSERT_EQ(0x100, msg);3112	ret = get_syscall(_metadata, child_pid);3113	EXPECT_TRUE(ret == __NR_nanosleep || ret == __NR_clock_nanosleep);3114 3115	/* Might as well check siginfo for sanity while we're here. */3116	ASSERT_EQ(0, ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &info));3117	ASSERT_EQ(SIGTRAP, info.si_signo);3118	ASSERT_EQ(SIGTRAP | (PTRACE_EVENT_SECCOMP << 8), info.si_code);3119	EXPECT_EQ(0, info.si_errno);3120	EXPECT_EQ(getuid(), info.si_uid);3121	/* Verify signal delivery came from child (seccomp-triggered). */3122	EXPECT_EQ(child_pid, info.si_pid);3123 3124	/* Interrupt nanosleep with SIGSTOP (which we'll need to handle). */3125	ASSERT_EQ(0, kill(child_pid, SIGSTOP));3126	ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));3127	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));3128	ASSERT_EQ(true, WIFSTOPPED(status));3129	ASSERT_EQ(SIGSTOP, WSTOPSIG(status));3130	ASSERT_EQ(0, ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &info));3131	/*3132	 * There is no siginfo on SIGSTOP any more, so we can't verify3133	 * signal delivery came from parent now (getpid() == info.si_pid).3134	 * https://lkml.kernel.org/r/CAGXu5jJaZAOzP1qFz66tYrtbuywqb+UN2SOA1VLHpCCOiYvYeg@mail.gmail.com3135	 * At least verify the SIGSTOP via PTRACE_GETSIGINFO.3136	 */3137	EXPECT_EQ(SIGSTOP, info.si_signo);3138 3139	/* Restart nanosleep with SIGCONT, which triggers restart_syscall. */3140	ASSERT_EQ(0, kill(child_pid, SIGCONT));3141	ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));3142	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));3143	ASSERT_EQ(true, WIFSTOPPED(status));3144	ASSERT_EQ(SIGCONT, WSTOPSIG(status));3145	ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));3146 3147	/* Wait for restart_syscall() to start. */3148	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));3149	ASSERT_EQ(true, WIFSTOPPED(status));3150	ASSERT_EQ(SIGTRAP, WSTOPSIG(status));3151	ASSERT_EQ(PTRACE_EVENT_SECCOMP, (status >> 16));3152	ASSERT_EQ(0, ptrace(PTRACE_GETEVENTMSG, child_pid, NULL, &msg));3153 3154	ASSERT_EQ(0x200, msg);3155	ret = get_syscall(_metadata, child_pid);3156#if defined(__arm__)3157	/*3158	 * FIXME:3159	 * - native ARM registers do NOT expose true syscall.3160	 * - compat ARM registers on ARM64 DO expose true syscall.3161	 */3162	ASSERT_EQ(0, uname(&utsbuf));3163	if (strncmp(utsbuf.machine, "arm", 3) == 0) {3164		EXPECT_EQ(__NR_nanosleep, ret);3165	} else3166#endif3167	{3168		EXPECT_EQ(__NR_restart_syscall, ret);3169	}3170 3171	/* Write again to end test. */3172	ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));3173	ASSERT_EQ(1, write(pipefd[1], "!", 1));3174	EXPECT_EQ(0, close(pipefd[1]));3175 3176	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));3177	if (WIFSIGNALED(status) || WEXITSTATUS(status))3178		_metadata->exit_code = KSFT_FAIL;3179}3180 3181TEST_SIGNAL(filter_flag_log, SIGSYS)3182{3183	struct sock_filter allow_filter[] = {3184		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),3185	};3186	struct sock_filter kill_filter[] = {3187		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,3188			offsetof(struct seccomp_data, nr)),3189		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 0, 1),3190		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),3191		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),3192	};3193	struct sock_fprog allow_prog = {3194		.len = (unsigned short)ARRAY_SIZE(allow_filter),3195		.filter = allow_filter,3196	};3197	struct sock_fprog kill_prog = {3198		.len = (unsigned short)ARRAY_SIZE(kill_filter),3199		.filter = kill_filter,3200	};3201	long ret;3202	pid_t parent = getppid();3203 3204	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);3205	ASSERT_EQ(0, ret);3206 3207	/* Verify that the FILTER_FLAG_LOG flag isn't accepted in strict mode */3208	ret = seccomp(SECCOMP_SET_MODE_STRICT, SECCOMP_FILTER_FLAG_LOG,3209		      &allow_prog);3210	ASSERT_NE(ENOSYS, errno) {3211		TH_LOG("Kernel does not support seccomp syscall!");3212	}3213	EXPECT_NE(0, ret) {3214		TH_LOG("Kernel accepted FILTER_FLAG_LOG flag in strict mode!");3215	}3216	EXPECT_EQ(EINVAL, errno) {3217		TH_LOG("Kernel returned unexpected errno for FILTER_FLAG_LOG flag in strict mode!");3218	}3219 3220	/* Verify that a simple, permissive filter can be added with no flags */3221	ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &allow_prog);3222	EXPECT_EQ(0, ret);3223 3224	/* See if the same filter can be added with the FILTER_FLAG_LOG flag */3225	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_LOG,3226		      &allow_prog);3227	ASSERT_NE(EINVAL, errno) {3228		TH_LOG("Kernel does not support the FILTER_FLAG_LOG flag!");3229	}3230	EXPECT_EQ(0, ret);3231 3232	/* Ensure that the kill filter works with the FILTER_FLAG_LOG flag */3233	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_LOG,3234		      &kill_prog);3235	EXPECT_EQ(0, ret);3236 3237	EXPECT_EQ(parent, syscall(__NR_getppid));3238	/* getpid() should never return. */3239	EXPECT_EQ(0, syscall(__NR_getpid));3240}3241 3242TEST(get_action_avail)3243{3244	__u32 actions[] = { SECCOMP_RET_KILL_THREAD, SECCOMP_RET_TRAP,3245			    SECCOMP_RET_ERRNO, SECCOMP_RET_TRACE,3246			    SECCOMP_RET_LOG,   SECCOMP_RET_ALLOW };3247	__u32 unknown_action = 0x10000000U;3248	int i;3249	long ret;3250 3251	ret = seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &actions[0]);3252	ASSERT_NE(ENOSYS, errno) {3253		TH_LOG("Kernel does not support seccomp syscall!");3254	}3255	ASSERT_NE(EINVAL, errno) {3256		TH_LOG("Kernel does not support SECCOMP_GET_ACTION_AVAIL operation!");3257	}3258	EXPECT_EQ(ret, 0);3259 3260	for (i = 0; i < ARRAY_SIZE(actions); i++) {3261		ret = seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &actions[i]);3262		EXPECT_EQ(ret, 0) {3263			TH_LOG("Expected action (0x%X) not available!",3264			       actions[i]);3265		}3266	}3267 3268	/* Check that an unknown action is handled properly (EOPNOTSUPP) */3269	ret = seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &unknown_action);3270	EXPECT_EQ(ret, -1);3271	EXPECT_EQ(errno, EOPNOTSUPP);3272}3273 3274TEST(get_metadata)3275{3276	pid_t pid;3277	int pipefd[2];3278	char buf;3279	struct seccomp_metadata md;3280	long ret;3281 3282	/* Only real root can get metadata. */3283	if (geteuid()) {3284		SKIP(return, "get_metadata requires real root");3285		return;3286	}3287 3288	ASSERT_EQ(0, pipe(pipefd));3289 3290	pid = fork();3291	ASSERT_GE(pid, 0);3292	if (pid == 0) {3293		struct sock_filter filter[] = {3294			BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),3295		};3296		struct sock_fprog prog = {3297			.len = (unsigned short)ARRAY_SIZE(filter),3298			.filter = filter,3299		};3300 3301		/* one with log, one without */3302		EXPECT_EQ(0, seccomp(SECCOMP_SET_MODE_FILTER,3303				     SECCOMP_FILTER_FLAG_LOG, &prog));3304		EXPECT_EQ(0, seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog));3305 3306		EXPECT_EQ(0, close(pipefd[0]));3307		ASSERT_EQ(1, write(pipefd[1], "1", 1));3308		ASSERT_EQ(0, close(pipefd[1]));3309 3310		while (1)3311			sleep(100);3312	}3313 3314	ASSERT_EQ(0, close(pipefd[1]));3315	ASSERT_EQ(1, read(pipefd[0], &buf, 1));3316 3317	ASSERT_EQ(0, ptrace(PTRACE_ATTACH, pid));3318	ASSERT_EQ(pid, waitpid(pid, NULL, 0));3319 3320	/* Past here must not use ASSERT or child process is never killed. */3321 3322	md.filter_off = 0;3323	errno = 0;3324	ret = ptrace(PTRACE_SECCOMP_GET_METADATA, pid, sizeof(md), &md);3325	EXPECT_EQ(sizeof(md), ret) {3326		if (errno == EINVAL)3327			SKIP(goto skip, "Kernel does not support PTRACE_SECCOMP_GET_METADATA (missing CONFIG_CHECKPOINT_RESTORE?)");3328	}3329 3330	EXPECT_EQ(md.flags, SECCOMP_FILTER_FLAG_LOG);3331	EXPECT_EQ(md.filter_off, 0);3332 3333	md.filter_off = 1;3334	ret = ptrace(PTRACE_SECCOMP_GET_METADATA, pid, sizeof(md), &md);3335	EXPECT_EQ(sizeof(md), ret);3336	EXPECT_EQ(md.flags, 0);3337	EXPECT_EQ(md.filter_off, 1);3338 3339skip:3340	ASSERT_EQ(0, kill(pid, SIGKILL));3341}3342 3343static int user_notif_syscall(int nr, unsigned int flags)3344{3345	struct sock_filter filter[] = {3346		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,3347			offsetof(struct seccomp_data, nr)),3348		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, nr, 0, 1),3349		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_USER_NOTIF),3350		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),3351	};3352 3353	struct sock_fprog prog = {3354		.len = (unsigned short)ARRAY_SIZE(filter),3355		.filter = filter,3356	};3357 3358	return seccomp(SECCOMP_SET_MODE_FILTER, flags, &prog);3359}3360 3361#define USER_NOTIF_MAGIC INT_MAX3362TEST(user_notification_basic)3363{3364	pid_t pid;3365	long ret;3366	int status, listener;3367	struct seccomp_notif req = {};3368	struct seccomp_notif_resp resp = {};3369	struct pollfd pollfd;3370 3371	struct sock_filter filter[] = {3372		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),3373	};3374	struct sock_fprog prog = {3375		.len = (unsigned short)ARRAY_SIZE(filter),3376		.filter = filter,3377	};3378 3379	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);3380	ASSERT_EQ(0, ret) {3381		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");3382	}3383 3384	pid = fork();3385	ASSERT_GE(pid, 0);3386 3387	/* Check that we get -ENOSYS with no listener attached */3388	if (pid == 0) {3389		if (user_notif_syscall(__NR_getppid, 0) < 0)3390			exit(1);3391		ret = syscall(__NR_getppid);3392		exit(ret >= 0 || errno != ENOSYS);3393	}3394 3395	EXPECT_EQ(waitpid(pid, &status, 0), pid);3396	EXPECT_EQ(true, WIFEXITED(status));3397	EXPECT_EQ(0, WEXITSTATUS(status));3398 3399	/* Add some no-op filters for grins. */3400	EXPECT_EQ(seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog), 0);3401	EXPECT_EQ(seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog), 0);3402	EXPECT_EQ(seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog), 0);3403	EXPECT_EQ(seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog), 0);3404 3405	/* Check that the basic notification machinery works */3406	listener = user_notif_syscall(__NR_getppid,3407				      SECCOMP_FILTER_FLAG_NEW_LISTENER);3408	ASSERT_GE(listener, 0);3409 3410	/* Installing a second listener in the chain should EBUSY */3411	EXPECT_EQ(user_notif_syscall(__NR_getppid,3412				     SECCOMP_FILTER_FLAG_NEW_LISTENER),3413		  -1);3414	EXPECT_EQ(errno, EBUSY);3415 3416	pid = fork();3417	ASSERT_GE(pid, 0);3418 3419	if (pid == 0) {3420		ret = syscall(__NR_getppid);3421		exit(ret != USER_NOTIF_MAGIC);3422	}3423 3424	pollfd.fd = listener;3425	pollfd.events = POLLIN | POLLOUT;3426 3427	EXPECT_GT(poll(&pollfd, 1, -1), 0);3428	EXPECT_EQ(pollfd.revents, POLLIN);3429 3430	/* Test that we can't pass garbage to the kernel. */3431	memset(&req, 0, sizeof(req));3432	req.pid = -1;3433	errno = 0;3434	ret = ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req);3435	EXPECT_EQ(-1, ret);3436	EXPECT_EQ(EINVAL, errno);3437 3438	if (ret) {3439		req.pid = 0;3440		EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);3441	}3442 3443	pollfd.fd = listener;3444	pollfd.events = POLLIN | POLLOUT;3445 3446	EXPECT_GT(poll(&pollfd, 1, -1), 0);3447	EXPECT_EQ(pollfd.revents, POLLOUT);3448 3449	EXPECT_EQ(req.data.nr,  __NR_getppid);3450 3451	resp.id = req.id;3452	resp.error = 0;3453	resp.val = USER_NOTIF_MAGIC;3454 3455	/* check that we make sure flags == 0 */3456	resp.flags = 1;3457	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), -1);3458	EXPECT_EQ(errno, EINVAL);3459 3460	resp.flags = 0;3461	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0);3462 3463	EXPECT_EQ(waitpid(pid, &status, 0), pid);3464	EXPECT_EQ(true, WIFEXITED(status));3465	EXPECT_EQ(0, WEXITSTATUS(status));3466}3467 3468TEST(user_notification_with_tsync)3469{3470	int ret;3471	unsigned int flags;3472 3473	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);3474	ASSERT_EQ(0, ret) {3475		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");3476	}3477 3478	/* these were exclusive */3479	flags = SECCOMP_FILTER_FLAG_NEW_LISTENER |3480		SECCOMP_FILTER_FLAG_TSYNC;3481	ASSERT_EQ(-1, user_notif_syscall(__NR_getppid, flags));3482	ASSERT_EQ(EINVAL, errno);3483 3484	/* but now they're not */3485	flags |= SECCOMP_FILTER_FLAG_TSYNC_ESRCH;3486	ret = user_notif_syscall(__NR_getppid, flags);3487	close(ret);3488	ASSERT_LE(0, ret);3489}3490 3491TEST(user_notification_kill_in_middle)3492{3493	pid_t pid;3494	long ret;3495	int listener;3496	struct seccomp_notif req = {};3497	struct seccomp_notif_resp resp = {};3498 3499	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);3500	ASSERT_EQ(0, ret) {3501		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");3502	}3503 3504	listener = user_notif_syscall(__NR_getppid,3505				      SECCOMP_FILTER_FLAG_NEW_LISTENER);3506	ASSERT_GE(listener, 0);3507 3508	/*3509	 * Check that nothing bad happens when we kill the task in the middle3510	 * of a syscall.3511	 */3512	pid = fork();3513	ASSERT_GE(pid, 0);3514 3515	if (pid == 0) {3516		ret = syscall(__NR_getppid);3517		exit(ret != USER_NOTIF_MAGIC);3518	}3519 3520	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);3521	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ID_VALID, &req.id), 0);3522 3523	EXPECT_EQ(kill(pid, SIGKILL), 0);3524	EXPECT_EQ(waitpid(pid, NULL, 0), pid);3525 3526	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ID_VALID, &req.id), -1);3527 3528	resp.id = req.id;3529	ret = ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp);3530	EXPECT_EQ(ret, -1);3531	EXPECT_EQ(errno, ENOENT);3532}3533 3534static int handled = -1;3535 3536static void signal_handler(int signal)3537{3538	if (write(handled, "c", 1) != 1)3539		perror("write from signal");3540}3541 3542TEST(user_notification_signal)3543{3544	pid_t pid;3545	long ret;3546	int status, listener, sk_pair[2];3547	struct seccomp_notif req = {};3548	struct seccomp_notif_resp resp = {};3549	char c;3550 3551	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);3552	ASSERT_EQ(0, ret) {3553		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");3554	}3555 3556	ASSERT_EQ(socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sk_pair), 0);3557 3558	listener = user_notif_syscall(__NR_gettid,3559				      SECCOMP_FILTER_FLAG_NEW_LISTENER);3560	ASSERT_GE(listener, 0);3561 3562	pid = fork();3563	ASSERT_GE(pid, 0);3564 3565	if (pid == 0) {3566		close(sk_pair[0]);3567		handled = sk_pair[1];3568		if (signal(SIGUSR1, signal_handler) == SIG_ERR) {3569			perror("signal");3570			exit(1);3571		}3572		/*3573		 * ERESTARTSYS behavior is a bit hard to test, because we need3574		 * to rely on a signal that has not yet been handled. Let's at3575		 * least check that the error code gets propagated through, and3576		 * hope that it doesn't break when there is actually a signal :)3577		 */3578		ret = syscall(__NR_gettid);3579		exit(!(ret == -1 && errno == 512));3580	}3581 3582	close(sk_pair[1]);3583 3584	memset(&req, 0, sizeof(req));3585	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);3586 3587	EXPECT_EQ(kill(pid, SIGUSR1), 0);3588 3589	/*3590	 * Make sure the signal really is delivered, which means we're not3591	 * stuck in the user notification code any more and the notification3592	 * should be dead.3593	 */3594	EXPECT_EQ(read(sk_pair[0], &c, 1), 1);3595 3596	resp.id = req.id;3597	resp.error = -EPERM;3598	resp.val = 0;3599 3600	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), -1);3601	EXPECT_EQ(errno, ENOENT);3602 3603	memset(&req, 0, sizeof(req));3604	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);3605 3606	resp.id = req.id;3607	resp.error = -512; /* -ERESTARTSYS */3608	resp.val = 0;3609 3610	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0);3611 3612	EXPECT_EQ(waitpid(pid, &status, 0), pid);3613	EXPECT_EQ(true, WIFEXITED(status));3614	EXPECT_EQ(0, WEXITSTATUS(status));3615}3616 3617TEST(user_notification_closed_listener)3618{3619	pid_t pid;3620	long ret;3621	int status, listener;3622 3623	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);3624	ASSERT_EQ(0, ret) {3625		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");3626	}3627 3628	listener = user_notif_syscall(__NR_getppid,3629				      SECCOMP_FILTER_FLAG_NEW_LISTENER);3630	ASSERT_GE(listener, 0);3631 3632	/*3633	 * Check that we get an ENOSYS when the listener is closed.3634	 */3635	pid = fork();3636	ASSERT_GE(pid, 0);3637	if (pid == 0) {3638		close(listener);3639		ret = syscall(__NR_getppid);3640		exit(ret != -1 && errno != ENOSYS);3641	}3642 3643	close(listener);3644 3645	EXPECT_EQ(waitpid(pid, &status, 0), pid);3646	EXPECT_EQ(true, WIFEXITED(status));3647	EXPECT_EQ(0, WEXITSTATUS(status));3648}3649 3650/*3651 * Check that a pid in a child namespace still shows up as valid in ours.3652 */3653TEST(user_notification_child_pid_ns)3654{3655	pid_t pid;3656	int status, listener;3657	struct seccomp_notif req = {};3658	struct seccomp_notif_resp resp = {};3659 3660	ASSERT_EQ(unshare(CLONE_NEWUSER | CLONE_NEWPID), 0) {3661		if (errno == EINVAL)3662			SKIP(return, "kernel missing CLONE_NEWUSER support");3663	};3664 3665	listener = user_notif_syscall(__NR_getppid,3666				      SECCOMP_FILTER_FLAG_NEW_LISTENER);3667	ASSERT_GE(listener, 0);3668 3669	pid = fork();3670	ASSERT_GE(pid, 0);3671 3672	if (pid == 0)3673		exit(syscall(__NR_getppid) != USER_NOTIF_MAGIC);3674 3675	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);3676	EXPECT_EQ(req.pid, pid);3677 3678	resp.id = req.id;3679	resp.error = 0;3680	resp.val = USER_NOTIF_MAGIC;3681 3682	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0);3683 3684	EXPECT_EQ(waitpid(pid, &status, 0), pid);3685	EXPECT_EQ(true, WIFEXITED(status));3686	EXPECT_EQ(0, WEXITSTATUS(status));3687	close(listener);3688}3689 3690/*3691 * Check that a pid in a sibling (i.e. unrelated) namespace shows up as 0, i.e.3692 * invalid.3693 */3694TEST(user_notification_sibling_pid_ns)3695{3696	pid_t pid, pid2;3697	int status, listener;3698	struct seccomp_notif req = {};3699	struct seccomp_notif_resp resp = {};3700 3701	ASSERT_EQ(prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0), 0) {3702		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");3703	}3704 3705	listener = user_notif_syscall(__NR_getppid,3706				      SECCOMP_FILTER_FLAG_NEW_LISTENER);3707	ASSERT_GE(listener, 0);3708 3709	pid = fork();3710	ASSERT_GE(pid, 0);3711 3712	if (pid == 0) {3713		ASSERT_EQ(unshare(CLONE_NEWPID), 0) {3714			if (errno == EPERM)3715				SKIP(return, "CLONE_NEWPID requires CAP_SYS_ADMIN");3716			else if (errno == EINVAL)3717				SKIP(return, "CLONE_NEWPID is invalid (missing CONFIG_PID_NS?)");3718		}3719 3720		pid2 = fork();3721		ASSERT_GE(pid2, 0);3722 3723		if (pid2 == 0)3724			exit(syscall(__NR_getppid) != USER_NOTIF_MAGIC);3725 3726		EXPECT_EQ(waitpid(pid2, &status, 0), pid2);3727		EXPECT_EQ(true, WIFEXITED(status));3728		EXPECT_EQ(0, WEXITSTATUS(status));3729		exit(WEXITSTATUS(status));3730	}3731 3732	/* Create the sibling ns, and sibling in it. */3733	ASSERT_EQ(unshare(CLONE_NEWPID), 0) {3734		if (errno == EPERM)3735			SKIP(return, "CLONE_NEWPID requires CAP_SYS_ADMIN");3736		else if (errno == EINVAL)3737			SKIP(return, "CLONE_NEWPID is invalid (missing CONFIG_PID_NS?)");3738	}3739	ASSERT_EQ(errno, 0);3740 3741	pid2 = fork();3742	ASSERT_GE(pid2, 0);3743 3744	if (pid2 == 0) {3745		ASSERT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);3746		/*3747		 * The pid should be 0, i.e. the task is in some namespace that3748		 * we can't "see".3749		 */3750		EXPECT_EQ(req.pid, 0);3751 3752		resp.id = req.id;3753		resp.error = 0;3754		resp.val = USER_NOTIF_MAGIC;3755 3756		ASSERT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0);3757		exit(0);3758	}3759 3760	close(listener);3761 3762	EXPECT_EQ(waitpid(pid, &status, 0), pid);3763	EXPECT_EQ(true, WIFEXITED(status));3764	EXPECT_EQ(0, WEXITSTATUS(status));3765 3766	EXPECT_EQ(waitpid(pid2, &status, 0), pid2);3767	EXPECT_EQ(true, WIFEXITED(status));3768	EXPECT_EQ(0, WEXITSTATUS(status));3769}3770 3771TEST(user_notification_fault_recv)3772{3773	pid_t pid;3774	int status, listener;3775	struct seccomp_notif req = {};3776	struct seccomp_notif_resp resp = {};3777 3778	ASSERT_EQ(unshare(CLONE_NEWUSER), 0) {3779		if (errno == EINVAL)3780			SKIP(return, "kernel missing CLONE_NEWUSER support");3781	}3782 3783	listener = user_notif_syscall(__NR_getppid,3784				      SECCOMP_FILTER_FLAG_NEW_LISTENER);3785	ASSERT_GE(listener, 0);3786 3787	pid = fork();3788	ASSERT_GE(pid, 0);3789 3790	if (pid == 0)3791		exit(syscall(__NR_getppid) != USER_NOTIF_MAGIC);3792 3793	/* Do a bad recv() */3794	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, NULL), -1);3795	EXPECT_EQ(errno, EFAULT);3796 3797	/* We should still be able to receive this notification, though. */3798	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);3799	EXPECT_EQ(req.pid, pid);3800 3801	resp.id = req.id;3802	resp.error = 0;3803	resp.val = USER_NOTIF_MAGIC;3804 3805	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0);3806 3807	EXPECT_EQ(waitpid(pid, &status, 0), pid);3808	EXPECT_EQ(true, WIFEXITED(status));3809	EXPECT_EQ(0, WEXITSTATUS(status));3810}3811 3812TEST(seccomp_get_notif_sizes)3813{3814	struct seccomp_notif_sizes sizes;3815 3816	ASSERT_EQ(seccomp(SECCOMP_GET_NOTIF_SIZES, 0, &sizes), 0);3817	EXPECT_EQ(sizes.seccomp_notif, sizeof(struct seccomp_notif));3818	EXPECT_EQ(sizes.seccomp_notif_resp, sizeof(struct seccomp_notif_resp));3819}3820 3821TEST(user_notification_continue)3822{3823	pid_t pid;3824	long ret;3825	int status, listener;3826	struct seccomp_notif req = {};3827	struct seccomp_notif_resp resp = {};3828	struct pollfd pollfd;3829 3830	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);3831	ASSERT_EQ(0, ret) {3832		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");3833	}3834 3835	listener = user_notif_syscall(__NR_dup, SECCOMP_FILTER_FLAG_NEW_LISTENER);3836	ASSERT_GE(listener, 0);3837 3838	pid = fork();3839	ASSERT_GE(pid, 0);3840 3841	if (pid == 0) {3842		int dup_fd, pipe_fds[2];3843		pid_t self;3844 3845		ASSERT_GE(pipe(pipe_fds), 0);3846 3847		dup_fd = dup(pipe_fds[0]);3848		ASSERT_GE(dup_fd, 0);3849		EXPECT_NE(pipe_fds[0], dup_fd);3850 3851		self = getpid();3852		ASSERT_EQ(filecmp(self, self, pipe_fds[0], dup_fd), 0);3853		exit(0);3854	}3855 3856	pollfd.fd = listener;3857	pollfd.events = POLLIN | POLLOUT;3858 3859	EXPECT_GT(poll(&pollfd, 1, -1), 0);3860	EXPECT_EQ(pollfd.revents, POLLIN);3861 3862	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);3863 3864	pollfd.fd = listener;3865	pollfd.events = POLLIN | POLLOUT;3866 3867	EXPECT_GT(poll(&pollfd, 1, -1), 0);3868	EXPECT_EQ(pollfd.revents, POLLOUT);3869 3870	EXPECT_EQ(req.data.nr, __NR_dup);3871 3872	resp.id = req.id;3873	resp.flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE;3874 3875	/*3876	 * Verify that setting SECCOMP_USER_NOTIF_FLAG_CONTINUE enforces other3877	 * args be set to 0.3878	 */3879	resp.error = 0;3880	resp.val = USER_NOTIF_MAGIC;3881	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), -1);3882	EXPECT_EQ(errno, EINVAL);3883 3884	resp.error = USER_NOTIF_MAGIC;3885	resp.val = 0;3886	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), -1);3887	EXPECT_EQ(errno, EINVAL);3888 3889	resp.error = 0;3890	resp.val = 0;3891	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0) {3892		if (errno == EINVAL)3893			SKIP(goto skip, "Kernel does not support SECCOMP_USER_NOTIF_FLAG_CONTINUE");3894	}3895 3896skip:3897	EXPECT_EQ(waitpid(pid, &status, 0), pid);3898	EXPECT_EQ(true, WIFEXITED(status));3899	EXPECT_EQ(0, WEXITSTATUS(status)) {3900		if (WEXITSTATUS(status) == 2) {3901			SKIP(return, "Kernel does not support kcmp() syscall");3902			return;3903		}3904	}3905}3906 3907TEST(user_notification_filter_empty)3908{3909	pid_t pid;3910	long ret;3911	int status;3912	struct pollfd pollfd;3913	struct __clone_args args = {3914		.flags = CLONE_FILES,3915		.exit_signal = SIGCHLD,3916	};3917 3918	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);3919	ASSERT_EQ(0, ret) {3920		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");3921	}3922 3923	if (__NR_clone3 < 0)3924		SKIP(return, "Test not built with clone3 support");3925 3926	pid = sys_clone3(&args, sizeof(args));3927	ASSERT_GE(pid, 0);3928 3929	if (pid == 0) {3930		int listener;3931 3932		listener = user_notif_syscall(__NR_mknodat, SECCOMP_FILTER_FLAG_NEW_LISTENER);3933		if (listener < 0)3934			_exit(EXIT_FAILURE);3935 3936		if (dup2(listener, 200) != 200)3937			_exit(EXIT_FAILURE);3938 3939		close(listener);3940 3941		_exit(EXIT_SUCCESS);3942	}3943 3944	EXPECT_EQ(waitpid(pid, &status, 0), pid);3945	EXPECT_EQ(true, WIFEXITED(status));3946	EXPECT_EQ(0, WEXITSTATUS(status));3947 3948	/*3949	 * The seccomp filter has become unused so we should be notified once3950	 * the kernel gets around to cleaning up task struct.3951	 */3952	pollfd.fd = 200;3953	pollfd.events = POLLHUP;3954 3955	EXPECT_GT(poll(&pollfd, 1, 2000), 0);3956	EXPECT_GT((pollfd.revents & POLLHUP) ?: 0, 0);3957}3958 3959TEST(user_ioctl_notification_filter_empty)3960{3961	pid_t pid;3962	long ret;3963	int status, p[2];3964	struct __clone_args args = {3965		.flags = CLONE_FILES,3966		.exit_signal = SIGCHLD,3967	};3968	struct seccomp_notif req = {};3969 3970	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);3971	ASSERT_EQ(0, ret) {3972		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");3973	}3974 3975	if (__NR_clone3 < 0)3976		SKIP(return, "Test not built with clone3 support");3977 3978	ASSERT_EQ(0, pipe(p));3979 3980	pid = sys_clone3(&args, sizeof(args));3981	ASSERT_GE(pid, 0);3982 3983	if (pid == 0) {3984		int listener;3985 3986		listener = user_notif_syscall(__NR_mknodat, SECCOMP_FILTER_FLAG_NEW_LISTENER);3987		if (listener < 0)3988			_exit(EXIT_FAILURE);3989 3990		if (dup2(listener, 200) != 200)3991			_exit(EXIT_FAILURE);3992		close(p[1]);3993		close(listener);3994		sleep(1);3995 3996		_exit(EXIT_SUCCESS);3997	}3998	if (read(p[0], &status, 1) != 0)3999		_exit(EXIT_SUCCESS);4000	close(p[0]);4001	/*4002	 * The seccomp filter has become unused so we should be notified once4003	 * the kernel gets around to cleaning up task struct.4004	 */4005	EXPECT_EQ(ioctl(200, SECCOMP_IOCTL_NOTIF_RECV, &req), -1);4006	EXPECT_EQ(errno, ENOENT);4007 4008	EXPECT_EQ(waitpid(pid, &status, 0), pid);4009	EXPECT_EQ(true, WIFEXITED(status));4010	EXPECT_EQ(0, WEXITSTATUS(status));4011}4012 4013static void *do_thread(void *data)4014{4015	return NULL;4016}4017 4018TEST(user_notification_filter_empty_threaded)4019{4020	pid_t pid;4021	long ret;4022	int status;4023	struct pollfd pollfd;4024	struct __clone_args args = {4025		.flags = CLONE_FILES,4026		.exit_signal = SIGCHLD,4027	};4028 4029	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);4030	ASSERT_EQ(0, ret) {4031		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");4032	}4033 4034	if (__NR_clone3 < 0)4035		SKIP(return, "Test not built with clone3 support");4036 4037	pid = sys_clone3(&args, sizeof(args));4038	ASSERT_GE(pid, 0);4039 4040	if (pid == 0) {4041		pid_t pid1, pid2;4042		int listener, status;4043		pthread_t thread;4044 4045		listener = user_notif_syscall(__NR_dup, SECCOMP_FILTER_FLAG_NEW_LISTENER);4046		if (listener < 0)4047			_exit(EXIT_FAILURE);4048 4049		if (dup2(listener, 200) != 200)4050			_exit(EXIT_FAILURE);4051 4052		close(listener);4053 4054		pid1 = fork();4055		if (pid1 < 0)4056			_exit(EXIT_FAILURE);4057 4058		if (pid1 == 0)4059			_exit(EXIT_SUCCESS);4060 4061		pid2 = fork();4062		if (pid2 < 0)4063			_exit(EXIT_FAILURE);4064 4065		if (pid2 == 0)4066			_exit(EXIT_SUCCESS);4067 4068		if (pthread_create(&thread, NULL, do_thread, NULL) ||4069		    pthread_join(thread, NULL))4070			_exit(EXIT_FAILURE);4071 4072		if (pthread_create(&thread, NULL, do_thread, NULL) ||4073		    pthread_join(thread, NULL))4074			_exit(EXIT_FAILURE);4075 4076		if (waitpid(pid1, &status, 0) != pid1 || !WIFEXITED(status) ||4077		    WEXITSTATUS(status))4078			_exit(EXIT_FAILURE);4079 4080		if (waitpid(pid2, &status, 0) != pid2 || !WIFEXITED(status) ||4081		    WEXITSTATUS(status))4082			_exit(EXIT_FAILURE);4083 4084		exit(EXIT_SUCCESS);4085	}4086 4087	EXPECT_EQ(waitpid(pid, &status, 0), pid);4088	EXPECT_EQ(true, WIFEXITED(status));4089	EXPECT_EQ(0, WEXITSTATUS(status));4090 4091	/*4092	 * The seccomp filter has become unused so we should be notified once4093	 * the kernel gets around to cleaning up task struct.4094	 */4095	pollfd.fd = 200;4096	pollfd.events = POLLHUP;4097 4098	EXPECT_GT(poll(&pollfd, 1, 2000), 0);4099	EXPECT_GT((pollfd.revents & POLLHUP) ?: 0, 0);4100}4101 4102 4103int get_next_fd(int prev_fd)4104{4105	for (int i = prev_fd + 1; i < FD_SETSIZE; ++i) {4106		if (fcntl(i, F_GETFD) == -1)4107			return i;4108	}4109	_exit(EXIT_FAILURE);4110}4111 4112TEST(user_notification_addfd)4113{4114	pid_t pid;4115	long ret;4116	int status, listener, memfd, fd, nextfd;4117	struct seccomp_notif_addfd addfd = {};4118	struct seccomp_notif_addfd_small small = {};4119	struct seccomp_notif_addfd_big big = {};4120	struct seccomp_notif req = {};4121	struct seccomp_notif_resp resp = {};4122	/* 100 ms */4123	struct timespec delay = { .tv_nsec = 100000000 };4124 4125	/* There may be arbitrary already-open fds at test start. */4126	memfd = memfd_create("test", 0);4127	ASSERT_GE(memfd, 0);4128	nextfd = get_next_fd(memfd);4129 4130	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);4131	ASSERT_EQ(0, ret) {4132		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");4133	}4134 4135	/* fd: 4 */4136	/* Check that the basic notification machinery works */4137	listener = user_notif_syscall(__NR_getppid,4138				      SECCOMP_FILTER_FLAG_NEW_LISTENER);4139	ASSERT_EQ(listener, nextfd);4140	nextfd = get_next_fd(nextfd);4141 4142	pid = fork();4143	ASSERT_GE(pid, 0);4144 4145	if (pid == 0) {4146		/* fds will be added and this value is expected */4147		if (syscall(__NR_getppid) != USER_NOTIF_MAGIC)4148			exit(1);4149 4150		/* Atomic addfd+send is received here. Check it is a valid fd */4151		if (fcntl(syscall(__NR_getppid), F_GETFD) == -1)4152			exit(1);4153 4154		exit(syscall(__NR_getppid) != USER_NOTIF_MAGIC);4155	}4156 4157	ASSERT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);4158 4159	addfd.srcfd = memfd;4160	addfd.newfd = 0;4161	addfd.id = req.id;4162	addfd.flags = 0x0;4163 4164	/* Verify bad newfd_flags cannot be set */4165	addfd.newfd_flags = ~O_CLOEXEC;4166	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd), -1);4167	EXPECT_EQ(errno, EINVAL);4168	addfd.newfd_flags = O_CLOEXEC;4169 4170	/* Verify bad flags cannot be set */4171	addfd.flags = 0xff;4172	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd), -1);4173	EXPECT_EQ(errno, EINVAL);4174	addfd.flags = 0;4175 4176	/* Verify that remote_fd cannot be set without setting flags */4177	addfd.newfd = 1;4178	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd), -1);4179	EXPECT_EQ(errno, EINVAL);4180	addfd.newfd = 0;4181 4182	/* Verify small size cannot be set */4183	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD_SMALL, &small), -1);4184	EXPECT_EQ(errno, EINVAL);4185 4186	/* Verify we can't send bits filled in unknown buffer area */4187	memset(&big, 0xAA, sizeof(big));4188	big.addfd = addfd;4189	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD_BIG, &big), -1);4190	EXPECT_EQ(errno, E2BIG);4191 4192 4193	/* Verify we can set an arbitrary remote fd */4194	fd = ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd);4195	EXPECT_EQ(fd, nextfd);4196	nextfd = get_next_fd(nextfd);4197	EXPECT_EQ(filecmp(getpid(), pid, memfd, fd), 0);4198 4199	/* Verify we can set an arbitrary remote fd with large size */4200	memset(&big, 0x0, sizeof(big));4201	big.addfd = addfd;4202	fd = ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD_BIG, &big);4203	EXPECT_EQ(fd, nextfd);4204	nextfd = get_next_fd(nextfd);4205 4206	/* Verify we can set a specific remote fd */4207	addfd.newfd = 42;4208	addfd.flags = SECCOMP_ADDFD_FLAG_SETFD;4209	fd = ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd);4210	EXPECT_EQ(fd, 42);4211	EXPECT_EQ(filecmp(getpid(), pid, memfd, fd), 0);4212 4213	/* Resume syscall */4214	resp.id = req.id;4215	resp.error = 0;4216	resp.val = USER_NOTIF_MAGIC;4217	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0);4218 4219	/*4220	 * This sets the ID of the ADD FD to the last request plus 1. The4221	 * notification ID increments 1 per notification.4222	 */4223	addfd.id = req.id + 1;4224 4225	/* This spins until the underlying notification is generated */4226	while (ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd) != -1 &&4227	       errno != -EINPROGRESS)4228		nanosleep(&delay, NULL);4229 4230	memset(&req, 0, sizeof(req));4231	ASSERT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);4232	ASSERT_EQ(addfd.id, req.id);4233 4234	/* Verify we can do an atomic addfd and send */4235	addfd.newfd = 0;4236	addfd.flags = SECCOMP_ADDFD_FLAG_SEND;4237	fd = ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd);4238	/*4239	 * Child has earlier "low" fds and now 42, so we expect the next4240	 * lowest available fd to be assigned here.4241	 */4242	EXPECT_EQ(fd, nextfd);4243	nextfd = get_next_fd(nextfd);4244	ASSERT_EQ(filecmp(getpid(), pid, memfd, fd), 0);4245 4246	/*4247	 * This sets the ID of the ADD FD to the last request plus 1. The4248	 * notification ID increments 1 per notification.4249	 */4250	addfd.id = req.id + 1;4251 4252	/* This spins until the underlying notification is generated */4253	while (ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd) != -1 &&4254	       errno != -EINPROGRESS)4255		nanosleep(&delay, NULL);4256 4257	memset(&req, 0, sizeof(req));4258	ASSERT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);4259	ASSERT_EQ(addfd.id, req.id);4260 4261	resp.id = req.id;4262	resp.error = 0;4263	resp.val = USER_NOTIF_MAGIC;4264	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0);4265 4266	/* Wait for child to finish. */4267	EXPECT_EQ(waitpid(pid, &status, 0), pid);4268	EXPECT_EQ(true, WIFEXITED(status));4269	EXPECT_EQ(0, WEXITSTATUS(status));4270 4271	close(memfd);4272}4273 4274TEST(user_notification_addfd_rlimit)4275{4276	pid_t pid;4277	long ret;4278	int status, listener, memfd;4279	struct seccomp_notif_addfd addfd = {};4280	struct seccomp_notif req = {};4281	struct seccomp_notif_resp resp = {};4282	const struct rlimit lim = {4283		.rlim_cur	= 0,4284		.rlim_max	= 0,4285	};4286 4287	memfd = memfd_create("test", 0);4288	ASSERT_GE(memfd, 0);4289 4290	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);4291	ASSERT_EQ(0, ret) {4292		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");4293	}4294 4295	/* Check that the basic notification machinery works */4296	listener = user_notif_syscall(__NR_getppid,4297				      SECCOMP_FILTER_FLAG_NEW_LISTENER);4298	ASSERT_GE(listener, 0);4299 4300	pid = fork();4301	ASSERT_GE(pid, 0);4302 4303	if (pid == 0)4304		exit(syscall(__NR_getppid) != USER_NOTIF_MAGIC);4305 4306 4307	ASSERT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);4308 4309	ASSERT_EQ(prlimit(pid, RLIMIT_NOFILE, &lim, NULL), 0);4310 4311	addfd.srcfd = memfd;4312	addfd.newfd_flags = O_CLOEXEC;4313	addfd.newfd = 0;4314	addfd.id = req.id;4315	addfd.flags = 0;4316 4317	/* Should probably spot check /proc/sys/fs/file-nr */4318	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd), -1);4319	EXPECT_EQ(errno, EMFILE);4320 4321	addfd.flags = SECCOMP_ADDFD_FLAG_SEND;4322	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd), -1);4323	EXPECT_EQ(errno, EMFILE);4324 4325	addfd.newfd = 100;4326	addfd.flags = SECCOMP_ADDFD_FLAG_SETFD;4327	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd), -1);4328	EXPECT_EQ(errno, EBADF);4329 4330	resp.id = req.id;4331	resp.error = 0;4332	resp.val = USER_NOTIF_MAGIC;4333 4334	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0);4335 4336	/* Wait for child to finish. */4337	EXPECT_EQ(waitpid(pid, &status, 0), pid);4338	EXPECT_EQ(true, WIFEXITED(status));4339	EXPECT_EQ(0, WEXITSTATUS(status));4340 4341	close(memfd);4342}4343 4344#ifndef SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP4345#define SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP (1UL << 0)4346#define SECCOMP_IOCTL_NOTIF_SET_FLAGS  SECCOMP_IOW(4, __u64)4347#endif4348 4349TEST(user_notification_sync)4350{4351	struct seccomp_notif req = {};4352	struct seccomp_notif_resp resp = {};4353	int status, listener;4354	pid_t pid;4355	long ret;4356 4357	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);4358	ASSERT_EQ(0, ret) {4359		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");4360	}4361 4362	listener = user_notif_syscall(__NR_getppid,4363				      SECCOMP_FILTER_FLAG_NEW_LISTENER);4364	ASSERT_GE(listener, 0);4365 4366	/* Try to set invalid flags. */4367	EXPECT_SYSCALL_RETURN(-EINVAL,4368		ioctl(listener, SECCOMP_IOCTL_NOTIF_SET_FLAGS, 0xffffffff, 0));4369 4370	ASSERT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SET_FLAGS,4371			SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP, 0), 0);4372 4373	pid = fork();4374	ASSERT_GE(pid, 0);4375	if (pid == 0) {4376		ret = syscall(__NR_getppid);4377		ASSERT_EQ(ret, USER_NOTIF_MAGIC) {4378			_exit(1);4379		}4380		_exit(0);4381	}4382 4383	req.pid = 0;4384	ASSERT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);4385 4386	ASSERT_EQ(req.data.nr,  __NR_getppid);4387 4388	resp.id = req.id;4389	resp.error = 0;4390	resp.val = USER_NOTIF_MAGIC;4391	resp.flags = 0;4392	ASSERT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0);4393 4394	ASSERT_EQ(waitpid(pid, &status, 0), pid);4395	ASSERT_EQ(status, 0);4396}4397 4398 4399/* Make sure PTRACE_O_SUSPEND_SECCOMP requires CAP_SYS_ADMIN. */4400FIXTURE(O_SUSPEND_SECCOMP) {4401	pid_t pid;4402};4403 4404FIXTURE_SETUP(O_SUSPEND_SECCOMP)4405{4406	ERRNO_FILTER(block_read, E2BIG);4407	cap_value_t cap_list[] = { CAP_SYS_ADMIN };4408	cap_t caps;4409 4410	self->pid = 0;4411 4412	/* make sure we don't have CAP_SYS_ADMIN */4413	caps = cap_get_proc();4414	ASSERT_NE(NULL, caps);4415	ASSERT_EQ(0, cap_set_flag(caps, CAP_EFFECTIVE, 1, cap_list, CAP_CLEAR));4416	ASSERT_EQ(0, cap_set_proc(caps));4417	cap_free(caps);4418 4419	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));4420	ASSERT_EQ(0, prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog_block_read));4421 4422	self->pid = fork();4423	ASSERT_GE(self->pid, 0);4424 4425	if (self->pid == 0) {4426		while (1)4427			pause();4428		_exit(127);4429	}4430}4431 4432FIXTURE_TEARDOWN(O_SUSPEND_SECCOMP)4433{4434	if (self->pid)4435		kill(self->pid, SIGKILL);4436}4437 4438TEST_F(O_SUSPEND_SECCOMP, setoptions)4439{4440	int wstatus;4441 4442	ASSERT_EQ(0, ptrace(PTRACE_ATTACH, self->pid, NULL, 0));4443	ASSERT_EQ(self->pid, wait(&wstatus));4444	ASSERT_EQ(-1, ptrace(PTRACE_SETOPTIONS, self->pid, NULL, PTRACE_O_SUSPEND_SECCOMP));4445	if (errno == EINVAL)4446		SKIP(return, "Kernel does not support PTRACE_O_SUSPEND_SECCOMP (missing CONFIG_CHECKPOINT_RESTORE?)");4447	ASSERT_EQ(EPERM, errno);4448}4449 4450TEST_F(O_SUSPEND_SECCOMP, seize)4451{4452	int ret;4453 4454	ret = ptrace(PTRACE_SEIZE, self->pid, NULL, PTRACE_O_SUSPEND_SECCOMP);4455	ASSERT_EQ(-1, ret);4456	if (errno == EINVAL)4457		SKIP(return, "Kernel does not support PTRACE_O_SUSPEND_SECCOMP (missing CONFIG_CHECKPOINT_RESTORE?)");4458	ASSERT_EQ(EPERM, errno);4459}4460 4461/*4462 * get_nth - Get the nth, space separated entry in a file.4463 *4464 * Returns the length of the read field.4465 * Throws error if field is zero-lengthed.4466 */4467static ssize_t get_nth(struct __test_metadata *_metadata, const char *path,4468		     const unsigned int position, char **entry)4469{4470	char *line = NULL;4471	unsigned int i;4472	ssize_t nread;4473	size_t len = 0;4474	FILE *f;4475 4476	f = fopen(path, "r");4477	ASSERT_NE(f, NULL) {4478		TH_LOG("Could not open %s: %s", path, strerror(errno));4479	}4480 4481	for (i = 0; i < position; i++) {4482		nread = getdelim(&line, &len, ' ', f);4483		ASSERT_GE(nread, 0) {4484			TH_LOG("Failed to read %d entry in file %s", i, path);4485		}4486	}4487	fclose(f);4488 4489	ASSERT_GT(nread, 0) {4490		TH_LOG("Entry in file %s had zero length", path);4491	}4492 4493	*entry = line;4494	return nread - 1;4495}4496 4497/* For a given PID, get the task state (D, R, etc...) */4498static char get_proc_stat(struct __test_metadata *_metadata, pid_t pid)4499{4500	char proc_path[100] = {0};4501	char status;4502	char *line;4503 4504	snprintf(proc_path, sizeof(proc_path), "/proc/%d/stat", pid);4505	ASSERT_EQ(get_nth(_metadata, proc_path, 3, &line), 1);4506 4507	status = *line;4508	free(line);4509 4510	return status;4511}4512 4513TEST(user_notification_fifo)4514{4515	struct seccomp_notif_resp resp = {};4516	struct seccomp_notif req = {};4517	int i, status, listener;4518	pid_t pid, pids[3];4519	__u64 baseid;4520	long ret;4521	/* 100 ms */4522	struct timespec delay = { .tv_nsec = 100000000 };4523 4524	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);4525	ASSERT_EQ(0, ret) {4526		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");4527	}4528 4529	/* Setup a listener */4530	listener = user_notif_syscall(__NR_getppid,4531				      SECCOMP_FILTER_FLAG_NEW_LISTENER);4532	ASSERT_GE(listener, 0);4533 4534	pid = fork();4535	ASSERT_GE(pid, 0);4536 4537	if (pid == 0) {4538		ret = syscall(__NR_getppid);4539		exit(ret != USER_NOTIF_MAGIC);4540	}4541 4542	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);4543	baseid = req.id + 1;4544 4545	resp.id = req.id;4546	resp.error = 0;4547	resp.val = USER_NOTIF_MAGIC;4548 4549	/* check that we make sure flags == 0 */4550	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0);4551 4552	EXPECT_EQ(waitpid(pid, &status, 0), pid);4553	EXPECT_EQ(true, WIFEXITED(status));4554	EXPECT_EQ(0, WEXITSTATUS(status));4555 4556	/* Start children, and generate notifications */4557	for (i = 0; i < ARRAY_SIZE(pids); i++) {4558		pid = fork();4559		if (pid == 0) {4560			ret = syscall(__NR_getppid);4561			exit(ret != USER_NOTIF_MAGIC);4562		}4563		pids[i] = pid;4564	}4565 4566	/* This spins until all of the children are sleeping */4567restart_wait:4568	for (i = 0; i < ARRAY_SIZE(pids); i++) {4569		if (get_proc_stat(_metadata, pids[i]) != 'S') {4570			nanosleep(&delay, NULL);4571			goto restart_wait;4572		}4573	}4574 4575	/* Read the notifications in order (and respond) */4576	for (i = 0; i < ARRAY_SIZE(pids); i++) {4577		memset(&req, 0, sizeof(req));4578		EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);4579		EXPECT_EQ(req.id, baseid + i);4580		resp.id = req.id;4581		EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0);4582	}4583 4584	/* Make sure notifications were received */4585	for (i = 0; i < ARRAY_SIZE(pids); i++) {4586		EXPECT_EQ(waitpid(pids[i], &status, 0), pids[i]);4587		EXPECT_EQ(true, WIFEXITED(status));4588		EXPECT_EQ(0, WEXITSTATUS(status));4589	}4590}4591 4592/* get_proc_syscall - Get the syscall in progress for a given pid4593 *4594 * Returns the current syscall number for a given process4595 * Returns -1 if not in syscall (running or blocked)4596 */4597static long get_proc_syscall(struct __test_metadata *_metadata, int pid)4598{4599	char proc_path[100] = {0};4600	long ret = -1;4601	ssize_t nread;4602	char *line;4603 4604	snprintf(proc_path, sizeof(proc_path), "/proc/%d/syscall", pid);4605	nread = get_nth(_metadata, proc_path, 1, &line);4606	ASSERT_GT(nread, 0);4607 4608	if (!strncmp("running", line, MIN(7, nread)))4609		ret = strtol(line, NULL, 16);4610 4611	free(line);4612	return ret;4613}4614 4615/* Ensure non-fatal signals prior to receive are unmodified */4616TEST(user_notification_wait_killable_pre_notification)4617{4618	struct sigaction new_action = {4619		.sa_handler = signal_handler,4620	};4621	int listener, status, sk_pair[2];4622	pid_t pid;4623	long ret;4624	char c;4625	/* 100 ms */4626	struct timespec delay = { .tv_nsec = 100000000 };4627 4628	ASSERT_EQ(sigemptyset(&new_action.sa_mask), 0);4629 4630	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);4631	ASSERT_EQ(0, ret)4632	{4633		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");4634	}4635 4636	ASSERT_EQ(socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sk_pair), 0);4637 4638	listener = user_notif_syscall(4639		__NR_getppid, SECCOMP_FILTER_FLAG_NEW_LISTENER |4640				      SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV);4641	ASSERT_GE(listener, 0);4642 4643	/*4644	 * Check that we can kill the process with SIGUSR1 prior to receiving4645	 * the notification. SIGUSR1 is wired up to a custom signal handler,4646	 * and make sure it gets called.4647	 */4648	pid = fork();4649	ASSERT_GE(pid, 0);4650 4651	if (pid == 0) {4652		close(sk_pair[0]);4653		handled = sk_pair[1];4654 4655		/* Setup the non-fatal sigaction without SA_RESTART */4656		if (sigaction(SIGUSR1, &new_action, NULL)) {4657			perror("sigaction");4658			exit(1);4659		}4660 4661		ret = syscall(__NR_getppid);4662		/* Make sure we got a return from a signal interruption */4663		exit(ret != -1 || errno != EINTR);4664	}4665 4666	/*4667	 * Make sure we've gotten to the seccomp user notification wait4668	 * from getppid prior to sending any signals4669	 */4670	while (get_proc_syscall(_metadata, pid) != __NR_getppid &&4671	       get_proc_stat(_metadata, pid) != 'S')4672		nanosleep(&delay, NULL);4673 4674	/* Send non-fatal kill signal */4675	EXPECT_EQ(kill(pid, SIGUSR1), 0);4676 4677	/* wait for process to exit (exit checks for EINTR) */4678	EXPECT_EQ(waitpid(pid, &status, 0), pid);4679	EXPECT_EQ(true, WIFEXITED(status));4680	EXPECT_EQ(0, WEXITSTATUS(status));4681 4682	EXPECT_EQ(read(sk_pair[0], &c, 1), 1);4683}4684 4685/* Ensure non-fatal signals after receive are blocked */4686TEST(user_notification_wait_killable)4687{4688	struct sigaction new_action = {4689		.sa_handler = signal_handler,4690	};4691	struct seccomp_notif_resp resp = {};4692	struct seccomp_notif req = {};4693	int listener, status, sk_pair[2];4694	pid_t pid;4695	long ret;4696	char c;4697	/* 100 ms */4698	struct timespec delay = { .tv_nsec = 100000000 };4699 4700	ASSERT_EQ(sigemptyset(&new_action.sa_mask), 0);4701 4702	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);4703	ASSERT_EQ(0, ret)4704	{4705		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");4706	}4707 4708	ASSERT_EQ(socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sk_pair), 0);4709 4710	listener = user_notif_syscall(4711		__NR_getppid, SECCOMP_FILTER_FLAG_NEW_LISTENER |4712				      SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV);4713	ASSERT_GE(listener, 0);4714 4715	pid = fork();4716	ASSERT_GE(pid, 0);4717 4718	if (pid == 0) {4719		close(sk_pair[0]);4720		handled = sk_pair[1];4721 4722		/* Setup the sigaction without SA_RESTART */4723		if (sigaction(SIGUSR1, &new_action, NULL)) {4724			perror("sigaction");4725			exit(1);4726		}4727 4728		/* Make sure that the syscall is completed (no EINTR) */4729		ret = syscall(__NR_getppid);4730		exit(ret != USER_NOTIF_MAGIC);4731	}4732 4733	/*4734	 * Get the notification, to make move the notifying process into a4735	 * non-preemptible (TASK_KILLABLE) state.4736	 */4737	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);4738	/* Send non-fatal kill signal */4739	EXPECT_EQ(kill(pid, SIGUSR1), 0);4740 4741	/*4742	 * Make sure the task enters moves to TASK_KILLABLE by waiting for4743	 * D (Disk Sleep) state after receiving non-fatal signal.4744	 */4745	while (get_proc_stat(_metadata, pid) != 'D')4746		nanosleep(&delay, NULL);4747 4748	resp.id = req.id;4749	resp.val = USER_NOTIF_MAGIC;4750	/* Make sure the notification is found and able to be replied to */4751	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0);4752 4753	/*4754	 * Make sure that the signal handler does get called once we're back in4755	 * userspace.4756	 */4757	EXPECT_EQ(read(sk_pair[0], &c, 1), 1);4758	/* wait for process to exit (exit checks for USER_NOTIF_MAGIC) */4759	EXPECT_EQ(waitpid(pid, &status, 0), pid);4760	EXPECT_EQ(true, WIFEXITED(status));4761	EXPECT_EQ(0, WEXITSTATUS(status));4762}4763 4764/* Ensure fatal signals after receive are not blocked */4765TEST(user_notification_wait_killable_fatal)4766{4767	struct seccomp_notif req = {};4768	int listener, status;4769	pid_t pid;4770	long ret;4771	/* 100 ms */4772	struct timespec delay = { .tv_nsec = 100000000 };4773 4774	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);4775	ASSERT_EQ(0, ret)4776	{4777		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");4778	}4779 4780	listener = user_notif_syscall(4781		__NR_getppid, SECCOMP_FILTER_FLAG_NEW_LISTENER |4782				      SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV);4783	ASSERT_GE(listener, 0);4784 4785	pid = fork();4786	ASSERT_GE(pid, 0);4787 4788	if (pid == 0) {4789		/* This should never complete as it should get a SIGTERM */4790		syscall(__NR_getppid);4791		exit(1);4792	}4793 4794	while (get_proc_stat(_metadata, pid) != 'S')4795		nanosleep(&delay, NULL);4796 4797	/*4798	 * Get the notification, to make move the notifying process into a4799	 * non-preemptible (TASK_KILLABLE) state.4800	 */4801	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);4802	/* Kill the process with a fatal signal */4803	EXPECT_EQ(kill(pid, SIGTERM), 0);4804 4805	/*4806	 * Wait for the process to exit, and make sure the process terminated4807	 * due to the SIGTERM signal.4808	 */4809	EXPECT_EQ(waitpid(pid, &status, 0), pid);4810	EXPECT_EQ(true, WIFSIGNALED(status));4811	EXPECT_EQ(SIGTERM, WTERMSIG(status));4812}4813 4814struct tsync_vs_thread_leader_args {4815	pthread_t leader;4816};4817 4818static void *tsync_vs_dead_thread_leader_sibling(void *_args)4819{4820	struct sock_filter allow_filter[] = {4821		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),4822	};4823	struct sock_fprog allow_prog = {4824		.len = (unsigned short)ARRAY_SIZE(allow_filter),4825		.filter = allow_filter,4826	};4827	struct tsync_vs_thread_leader_args *args = _args;4828	void *retval;4829	long ret;4830 4831	ret = pthread_join(args->leader, &retval);4832	if (ret)4833		exit(1);4834	if (retval != _args)4835		exit(2);4836	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC, &allow_prog);4837	if (ret)4838		exit(3);4839 4840	exit(0);4841}4842 4843/*4844 * Ensure that a dead thread leader doesn't prevent installing new filters with4845 * SECCOMP_FILTER_FLAG_TSYNC from other threads.4846 */4847TEST(tsync_vs_dead_thread_leader)4848{4849	int status;4850	pid_t pid;4851	long ret;4852 4853	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);4854	ASSERT_EQ(0, ret) {4855		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");4856	}4857 4858	pid = fork();4859	ASSERT_GE(pid, 0);4860 4861	if (pid == 0) {4862		struct sock_filter allow_filter[] = {4863			BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),4864		};4865		struct sock_fprog allow_prog = {4866			.len = (unsigned short)ARRAY_SIZE(allow_filter),4867			.filter = allow_filter,4868		};4869		struct  tsync_vs_thread_leader_args *args;4870		pthread_t sibling;4871 4872		args = malloc(sizeof(*args));4873		ASSERT_NE(NULL, args);4874		args->leader = pthread_self();4875 4876		ret = pthread_create(&sibling, NULL,4877				     tsync_vs_dead_thread_leader_sibling, args);4878		ASSERT_EQ(0, ret);4879 4880		/* Install a new filter just to the leader thread. */4881		ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &allow_prog);4882		ASSERT_EQ(0, ret);4883		pthread_exit(args);4884		exit(1);4885	}4886 4887	EXPECT_EQ(pid, waitpid(pid, &status, 0));4888	EXPECT_EQ(0, status);4889}4890 4891/*4892 * TODO:4893 * - expand NNP testing4894 * - better arch-specific TRACE and TRAP handlers.4895 * - endianness checking when appropriate4896 * - 64-bit arg prodding4897 * - arch value testing (x86 modes especially)4898 * - verify that FILTER_FLAG_LOG filters generate log messages4899 * - verify that RET_LOG generates log messages4900 */4901 4902TEST_HARNESS_MAIN4903