seccomp.c 32.5 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
L
Linus Torvalds 已提交
2 3 4 5 6
/*
 * linux/kernel/seccomp.c
 *
 * Copyright 2004-2005  Andrea Arcangeli <andrea@cpushare.com>
 *
7 8 9 10 11 12 13 14
 * Copyright (C) 2012 Google, Inc.
 * Will Drewry <wad@chromium.org>
 *
 * This defines a simple but solid secure-computing facility.
 *
 * Mode 1 uses a fixed list of allowed system calls.
 * Mode 2 allows user-defined system call filters in the form
 *        of Berkeley Packet Filters/Linux Socket Filters.
L
Linus Torvalds 已提交
15 16
 */

17
#include <linux/refcount.h>
18
#include <linux/audit.h>
19
#include <linux/compat.h>
20
#include <linux/coredump.h>
21
#include <linux/kmemleak.h>
22
#include <linux/sched.h>
23
#include <linux/sched/task_stack.h>
24
#include <linux/seccomp.h>
25
#include <linux/slab.h>
K
Kees Cook 已提交
26
#include <linux/syscalls.h>
27
#include <linux/sysctl.h>
L
Linus Torvalds 已提交
28

29
#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
30
#include <asm/syscall.h>
31
#endif
32 33 34

#ifdef CONFIG_SECCOMP_FILTER
#include <linux/filter.h>
35
#include <linux/pid.h>
36
#include <linux/ptrace.h>
37 38 39 40 41 42 43 44 45 46 47
#include <linux/security.h>
#include <linux/tracehook.h>
#include <linux/uaccess.h>

/**
 * struct seccomp_filter - container for seccomp BPF programs
 *
 * @usage: reference count to manage the object lifetime.
 *         get/put helpers should be used when accessing an instance
 *         outside of a lifetime-guarded section.  In general, this
 *         is only needed for handling filters shared across tasks.
48
 * @log: true if all actions except for SECCOMP_RET_ALLOW should be logged
49
 * @prev: points to a previously installed, or inherited, filter
M
Mickaël Salaün 已提交
50
 * @prog: the BPF program to evaluate
51 52 53 54 55 56 57 58 59 60 61 62
 *
 * seccomp_filter objects are organized in a tree linked via the @prev
 * pointer.  For any task, it appears to be a singly-linked list starting
 * with current->seccomp.filter, the most recently attached or inherited filter.
 * However, multiple filters may share a @prev node, by way of fork(), which
 * results in a unidirectional tree existing in memory.  This is similar to
 * how namespaces work.
 *
 * seccomp_filter objects should never be modified after being attached
 * to a task_struct (other than @usage).
 */
struct seccomp_filter {
63
	refcount_t usage;
64
	bool log;
65
	struct seccomp_filter *prev;
66
	struct bpf_prog *prog;
67 68 69 70 71
};

/* Limit any path through the tree to 256KB worth of instructions. */
#define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))

72
/*
73 74 75
 * Endianness is explicitly ignored and left for BPF program authors to manage
 * as per the specific architecture.
 */
76
static void populate_seccomp_data(struct seccomp_data *sd)
77
{
78 79
	struct task_struct *task = current;
	struct pt_regs *regs = task_pt_regs(task);
80
	unsigned long args[6];
81

82
	sd->nr = syscall_get_nr(task, regs);
83
	sd->arch = syscall_get_arch();
84 85 86 87 88 89 90
	syscall_get_arguments(task, regs, 0, 6, args);
	sd->args[0] = args[0];
	sd->args[1] = args[1];
	sd->args[2] = args[2];
	sd->args[3] = args[3];
	sd->args[4] = args[4];
	sd->args[5] = args[5];
91
	sd->instruction_pointer = KSTK_EIP(task);
92 93 94 95 96 97 98
}

/**
 *	seccomp_check_filter - verify seccomp filter code
 *	@filter: filter to verify
 *	@flen: length of filter
 *
99
 * Takes a previously checked filter (by bpf_check_classic) and
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
 * redirects all filter code that loads struct sk_buff data
 * and related data through seccomp_bpf_load.  It also
 * enforces length and alignment checking of those loads.
 *
 * Returns 0 if the rule set is legal or -EINVAL if not.
 */
static int seccomp_check_filter(struct sock_filter *filter, unsigned int flen)
{
	int pc;
	for (pc = 0; pc < flen; pc++) {
		struct sock_filter *ftest = &filter[pc];
		u16 code = ftest->code;
		u32 k = ftest->k;

		switch (code) {
115
		case BPF_LD | BPF_W | BPF_ABS:
116
			ftest->code = BPF_LDX | BPF_W | BPF_ABS;
117 118 119 120
			/* 32-bit aligned and not out of bounds. */
			if (k >= sizeof(struct seccomp_data) || k & 3)
				return -EINVAL;
			continue;
121
		case BPF_LD | BPF_W | BPF_LEN:
122
			ftest->code = BPF_LD | BPF_IMM;
123 124
			ftest->k = sizeof(struct seccomp_data);
			continue;
125
		case BPF_LDX | BPF_W | BPF_LEN:
126
			ftest->code = BPF_LDX | BPF_IMM;
127 128 129
			ftest->k = sizeof(struct seccomp_data);
			continue;
		/* Explicitly include allowed calls. */
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
		case BPF_RET | BPF_K:
		case BPF_RET | BPF_A:
		case BPF_ALU | BPF_ADD | BPF_K:
		case BPF_ALU | BPF_ADD | BPF_X:
		case BPF_ALU | BPF_SUB | BPF_K:
		case BPF_ALU | BPF_SUB | BPF_X:
		case BPF_ALU | BPF_MUL | BPF_K:
		case BPF_ALU | BPF_MUL | BPF_X:
		case BPF_ALU | BPF_DIV | BPF_K:
		case BPF_ALU | BPF_DIV | BPF_X:
		case BPF_ALU | BPF_AND | BPF_K:
		case BPF_ALU | BPF_AND | BPF_X:
		case BPF_ALU | BPF_OR | BPF_K:
		case BPF_ALU | BPF_OR | BPF_X:
		case BPF_ALU | BPF_XOR | BPF_K:
		case BPF_ALU | BPF_XOR | BPF_X:
		case BPF_ALU | BPF_LSH | BPF_K:
		case BPF_ALU | BPF_LSH | BPF_X:
		case BPF_ALU | BPF_RSH | BPF_K:
		case BPF_ALU | BPF_RSH | BPF_X:
		case BPF_ALU | BPF_NEG:
		case BPF_LD | BPF_IMM:
		case BPF_LDX | BPF_IMM:
		case BPF_MISC | BPF_TAX:
		case BPF_MISC | BPF_TXA:
		case BPF_LD | BPF_MEM:
		case BPF_LDX | BPF_MEM:
		case BPF_ST:
		case BPF_STX:
		case BPF_JMP | BPF_JA:
		case BPF_JMP | BPF_JEQ | BPF_K:
		case BPF_JMP | BPF_JEQ | BPF_X:
		case BPF_JMP | BPF_JGE | BPF_K:
		case BPF_JMP | BPF_JGE | BPF_X:
		case BPF_JMP | BPF_JGT | BPF_K:
		case BPF_JMP | BPF_JGT | BPF_X:
		case BPF_JMP | BPF_JSET | BPF_K:
		case BPF_JMP | BPF_JSET | BPF_X:
168 169 170 171 172 173 174 175 176
			continue;
		default:
			return -EINVAL;
		}
	}
	return 0;
}

/**
M
Mickaël Salaün 已提交
177 178
 * seccomp_run_filters - evaluates all seccomp filters against @sd
 * @sd: optional seccomp data to be passed to filters
179 180 181
 * @match: stores struct seccomp_filter that resulted in the return value,
 *         unless filter returned SECCOMP_RET_ALLOW, in which case it will
 *         be unchanged.
182 183 184
 *
 * Returns valid seccomp BPF response codes.
 */
185
#define ACTION_ONLY(ret) ((s32)((ret) & (SECCOMP_RET_ACTION_FULL)))
186 187
static u32 seccomp_run_filters(const struct seccomp_data *sd,
			       struct seccomp_filter **match)
188
{
189
	struct seccomp_data sd_local;
W
Will Drewry 已提交
190
	u32 ret = SECCOMP_RET_ALLOW;
191 192
	/* Make sure cross-thread synced filter points somewhere sane. */
	struct seccomp_filter *f =
193
			READ_ONCE(current->seccomp.filter);
W
Will Drewry 已提交
194 195

	/* Ensure unexpected behavior doesn't result in failing open. */
196
	if (unlikely(WARN_ON(f == NULL)))
197
		return SECCOMP_RET_KILL_PROCESS;
W
Will Drewry 已提交
198

199 200 201 202
	if (!sd) {
		populate_seccomp_data(&sd_local);
		sd = &sd_local;
	}
203

204 205
	/*
	 * All filters in the list are evaluated and the lowest BPF return
W
Will Drewry 已提交
206
	 * value always takes priority (ignoring the DATA).
207
	 */
208
	for (; f; f = f->prev) {
209
		u32 cur_ret = BPF_PROG_RUN(f->prog, sd);
210

211
		if (ACTION_ONLY(cur_ret) < ACTION_ONLY(ret)) {
W
Will Drewry 已提交
212
			ret = cur_ret;
213 214
			*match = f;
		}
215 216 217
	}
	return ret;
}
218
#endif /* CONFIG_SECCOMP_FILTER */
219

220 221
static inline bool seccomp_may_assign_mode(unsigned long seccomp_mode)
{
222
	assert_spin_locked(&current->sighand->siglock);
K
Kees Cook 已提交
223

224 225 226 227 228 229
	if (current->seccomp.mode && current->seccomp.mode != seccomp_mode)
		return false;

	return true;
}

230 231
static inline void seccomp_assign_mode(struct task_struct *task,
				       unsigned long seccomp_mode)
232
{
233
	assert_spin_locked(&task->sighand->siglock);
K
Kees Cook 已提交
234

235 236 237 238 239 240 241
	task->seccomp.mode = seccomp_mode;
	/*
	 * Make sure TIF_SECCOMP cannot be set before the mode (and
	 * filter) is set.
	 */
	smp_mb__before_atomic();
	set_tsk_thread_flag(task, TIF_SECCOMP);
242 243 244
}

#ifdef CONFIG_SECCOMP_FILTER
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
/* Returns 1 if the parent is an ancestor of the child. */
static int is_ancestor(struct seccomp_filter *parent,
		       struct seccomp_filter *child)
{
	/* NULL is the root ancestor. */
	if (parent == NULL)
		return 1;
	for (; child; child = child->prev)
		if (child == parent)
			return 1;
	return 0;
}

/**
 * seccomp_can_sync_threads: checks if all threads can be synchronized
 *
 * Expects sighand and cred_guard_mutex locks to be held.
 *
 * Returns 0 on success, -ve on error, or the pid of a thread which was
 * either not in the correct seccomp mode or it did not have an ancestral
 * seccomp filter.
 */
static inline pid_t seccomp_can_sync_threads(void)
{
	struct task_struct *thread, *caller;

	BUG_ON(!mutex_is_locked(&current->signal->cred_guard_mutex));
272
	assert_spin_locked(&current->sighand->siglock);
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312

	/* Validate all threads being eligible for synchronization. */
	caller = current;
	for_each_thread(caller, thread) {
		pid_t failed;

		/* Skip current, since it is initiating the sync. */
		if (thread == caller)
			continue;

		if (thread->seccomp.mode == SECCOMP_MODE_DISABLED ||
		    (thread->seccomp.mode == SECCOMP_MODE_FILTER &&
		     is_ancestor(thread->seccomp.filter,
				 caller->seccomp.filter)))
			continue;

		/* Return the first thread that cannot be synchronized. */
		failed = task_pid_vnr(thread);
		/* If the pid cannot be resolved, then return -ESRCH */
		if (unlikely(WARN_ON(failed == 0)))
			failed = -ESRCH;
		return failed;
	}

	return 0;
}

/**
 * seccomp_sync_threads: sets all threads to use current's filter
 *
 * Expects sighand and cred_guard_mutex locks to be held, and for
 * seccomp_can_sync_threads() to have returned success already
 * without dropping the locks.
 *
 */
static inline void seccomp_sync_threads(void)
{
	struct task_struct *thread, *caller;

	BUG_ON(!mutex_is_locked(&current->signal->cred_guard_mutex));
313
	assert_spin_locked(&current->sighand->siglock);
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331

	/* Synchronize all threads. */
	caller = current;
	for_each_thread(caller, thread) {
		/* Skip current, since it needs no changes. */
		if (thread == caller)
			continue;

		/* Get a task reference for the new leaf node. */
		get_seccomp_filter(caller);
		/*
		 * Drop the task reference to the shared ancestor since
		 * current's path will hold a reference.  (This also
		 * allows a put before the assignment.)
		 */
		put_seccomp_filter(thread);
		smp_store_release(&thread->seccomp.filter,
				  caller->seccomp.filter);
332 333 334 335 336 337 338 339 340 341

		/*
		 * Don't let an unprivileged task work around
		 * the no_new_privs restriction by creating
		 * a thread that sets it up, enters seccomp,
		 * then dies.
		 */
		if (task_no_new_privs(caller))
			task_set_no_new_privs(thread);

342 343 344 345 346 347
		/*
		 * Opt the other thread into seccomp if needed.
		 * As threads are considered to be trust-realm
		 * equivalent (see ptrace_may_access), it is safe to
		 * allow one thread to transition the other.
		 */
348
		if (thread->seccomp.mode == SECCOMP_MODE_DISABLED)
349 350 351 352
			seccomp_assign_mode(thread, SECCOMP_MODE_FILTER);
	}
}

353
/**
354
 * seccomp_prepare_filter: Prepares a seccomp filter for use.
355 356
 * @fprog: BPF program to install
 *
357
 * Returns filter on success or an ERR_PTR on failure.
358
 */
359
static struct seccomp_filter *seccomp_prepare_filter(struct sock_fprog *fprog)
360
{
361 362
	struct seccomp_filter *sfilter;
	int ret;
363
	const bool save_orig = IS_ENABLED(CONFIG_CHECKPOINT_RESTORE);
364 365

	if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)
366
		return ERR_PTR(-EINVAL);
367

368
	BUG_ON(INT_MAX / fprog->len < sizeof(struct sock_filter));
369 370

	/*
371
	 * Installing a seccomp filter requires that the task has
372 373 374 375
	 * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.
	 * This avoids scenarios where unprivileged tasks can affect the
	 * behavior of privileged children.
	 */
376
	if (!task_no_new_privs(current) &&
377 378
	    security_capable_noaudit(current_cred(), current_user_ns(),
				     CAP_SYS_ADMIN) != 0)
379
		return ERR_PTR(-EACCES);
380

381
	/* Allocate a new seccomp_filter */
382 383
	sfilter = kzalloc(sizeof(*sfilter), GFP_KERNEL | __GFP_NOWARN);
	if (!sfilter)
384
		return ERR_PTR(-ENOMEM);
385 386

	ret = bpf_prog_create_from_user(&sfilter->prog, fprog,
387
					seccomp_check_filter, save_orig);
388 389 390
	if (ret < 0) {
		kfree(sfilter);
		return ERR_PTR(ret);
391
	}
392

393
	refcount_set(&sfilter->usage, 1);
394

395
	return sfilter;
396 397 398
}

/**
399
 * seccomp_prepare_user_filter - prepares a user-supplied sock_fprog
400 401 402 403
 * @user_filter: pointer to the user data containing a sock_fprog.
 *
 * Returns 0 on success and non-zero otherwise.
 */
404 405
static struct seccomp_filter *
seccomp_prepare_user_filter(const char __user *user_filter)
406 407
{
	struct sock_fprog fprog;
408
	struct seccomp_filter *filter = ERR_PTR(-EFAULT);
409 410

#ifdef CONFIG_COMPAT
411
	if (in_compat_syscall()) {
412 413 414 415 416 417 418 419 420
		struct compat_sock_fprog fprog32;
		if (copy_from_user(&fprog32, user_filter, sizeof(fprog32)))
			goto out;
		fprog.len = fprog32.len;
		fprog.filter = compat_ptr(fprog32.filter);
	} else /* falls through to the if below. */
#endif
	if (copy_from_user(&fprog, user_filter, sizeof(fprog)))
		goto out;
421
	filter = seccomp_prepare_filter(&fprog);
422
out:
423 424 425 426 427 428 429 430
	return filter;
}

/**
 * seccomp_attach_filter: validate and attach filter
 * @flags:  flags to change filter behavior
 * @filter: seccomp filter to add to the current process
 *
K
Kees Cook 已提交
431 432
 * Caller must be holding current->sighand->siglock lock.
 *
433 434 435 436 437 438 439 440
 * Returns 0 on success, -ve on error.
 */
static long seccomp_attach_filter(unsigned int flags,
				  struct seccomp_filter *filter)
{
	unsigned long total_insns;
	struct seccomp_filter *walker;

441
	assert_spin_locked(&current->sighand->siglock);
K
Kees Cook 已提交
442

443 444 445 446 447 448 449
	/* Validate resulting filter length. */
	total_insns = filter->prog->len;
	for (walker = current->seccomp.filter; walker; walker = walker->prev)
		total_insns += walker->prog->len + 4;  /* 4 instr penalty */
	if (total_insns > MAX_INSNS_PER_PATH)
		return -ENOMEM;

450 451 452 453 454 455 456 457 458
	/* If thread sync has been requested, check that it is possible. */
	if (flags & SECCOMP_FILTER_FLAG_TSYNC) {
		int ret;

		ret = seccomp_can_sync_threads();
		if (ret)
			return ret;
	}

459 460 461 462
	/* Set log flag, if present. */
	if (flags & SECCOMP_FILTER_FLAG_LOG)
		filter->log = true;

463 464 465 466 467 468 469
	/*
	 * If there is an existing filter, make it the prev and don't drop its
	 * task reference.
	 */
	filter->prev = current->seccomp.filter;
	current->seccomp.filter = filter;

470 471 472 473
	/* Now that the new filter is in place, synchronize to all threads. */
	if (flags & SECCOMP_FILTER_FLAG_TSYNC)
		seccomp_sync_threads();

474
	return 0;
475 476
}

477
static void __get_seccomp_filter(struct seccomp_filter *filter)
478 479 480 481 482
{
	/* Reference count is bounded by the number of total processes. */
	refcount_inc(&filter->usage);
}

483 484 485 486 487 488
/* get_seccomp_filter - increments the reference count of the filter on @tsk */
void get_seccomp_filter(struct task_struct *tsk)
{
	struct seccomp_filter *orig = tsk->seccomp.filter;
	if (!orig)
		return;
489
	__get_seccomp_filter(orig);
490 491
}

492 493 494
static inline void seccomp_filter_free(struct seccomp_filter *filter)
{
	if (filter) {
495
		bpf_prog_destroy(filter->prog);
496 497 498 499
		kfree(filter);
	}
}

500
static void __put_seccomp_filter(struct seccomp_filter *orig)
501 502
{
	/* Clean up single-reference branches iteratively. */
503
	while (orig && refcount_dec_and_test(&orig->usage)) {
504 505
		struct seccomp_filter *freeme = orig;
		orig = orig->prev;
506
		seccomp_filter_free(freeme);
507 508
	}
}
W
Will Drewry 已提交
509

510 511 512 513 514 515
/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */
void put_seccomp_filter(struct task_struct *tsk)
{
	__put_seccomp_filter(tsk->seccomp.filter);
}

516 517 518 519 520 521 522 523 524 525 526
static void seccomp_init_siginfo(siginfo_t *info, int syscall, int reason)
{
	memset(info, 0, sizeof(*info));
	info->si_signo = SIGSYS;
	info->si_code = SYS_SECCOMP;
	info->si_call_addr = (void __user *)KSTK_EIP(current);
	info->si_errno = reason;
	info->si_arch = syscall_get_arch();
	info->si_syscall = syscall;
}

W
Will Drewry 已提交
527 528 529 530 531 532 533 534 535 536
/**
 * seccomp_send_sigsys - signals the task to allow in-process syscall emulation
 * @syscall: syscall number to send to userland
 * @reason: filter-supplied reason code to send to userland (via si_errno)
 *
 * Forces a SIGSYS with a code of SYS_SECCOMP and related sigsys info.
 */
static void seccomp_send_sigsys(int syscall, int reason)
{
	struct siginfo info;
537
	seccomp_init_siginfo(&info, syscall, reason);
W
Will Drewry 已提交
538 539
	force_sig_info(SIGSYS, &info, current);
}
540
#endif	/* CONFIG_SECCOMP_FILTER */
L
Linus Torvalds 已提交
541

542
/* For use with seccomp_actions_logged */
543 544
#define SECCOMP_LOG_KILL_PROCESS	(1 << 0)
#define SECCOMP_LOG_KILL_THREAD		(1 << 1)
545 546 547
#define SECCOMP_LOG_TRAP		(1 << 2)
#define SECCOMP_LOG_ERRNO		(1 << 3)
#define SECCOMP_LOG_TRACE		(1 << 4)
548 549
#define SECCOMP_LOG_LOG			(1 << 5)
#define SECCOMP_LOG_ALLOW		(1 << 6)
550

551 552
static u32 seccomp_actions_logged = SECCOMP_LOG_KILL_PROCESS |
				    SECCOMP_LOG_KILL_THREAD  |
553 554 555
				    SECCOMP_LOG_TRAP  |
				    SECCOMP_LOG_ERRNO |
				    SECCOMP_LOG_TRACE |
556
				    SECCOMP_LOG_LOG;
557

558 559
static inline void seccomp_log(unsigned long syscall, long signr, u32 action,
			       bool requested)
560 561 562 563 564
{
	bool log = false;

	switch (action) {
	case SECCOMP_RET_ALLOW:
565
		break;
566
	case SECCOMP_RET_TRAP:
567 568
		log = requested && seccomp_actions_logged & SECCOMP_LOG_TRAP;
		break;
569
	case SECCOMP_RET_ERRNO:
570 571
		log = requested && seccomp_actions_logged & SECCOMP_LOG_ERRNO;
		break;
572
	case SECCOMP_RET_TRACE:
573
		log = requested && seccomp_actions_logged & SECCOMP_LOG_TRACE;
574
		break;
575 576 577
	case SECCOMP_RET_LOG:
		log = seccomp_actions_logged & SECCOMP_LOG_LOG;
		break;
578 579
	case SECCOMP_RET_KILL_THREAD:
		log = seccomp_actions_logged & SECCOMP_LOG_KILL_THREAD;
580 581 582 583
		break;
	case SECCOMP_RET_KILL_PROCESS:
	default:
		log = seccomp_actions_logged & SECCOMP_LOG_KILL_PROCESS;
584 585 586
	}

	/*
587
	 * Force an audit message to be emitted when the action is RET_KILL_*,
588 589
	 * RET_LOG, or the FILTER_FLAG_LOG bit was set and the action is
	 * allowed to be logged by the admin.
590 591 592 593 594 595 596 597 598 599 600
	 */
	if (log)
		return __audit_seccomp(syscall, signr, action);

	/*
	 * Let the audit subsystem decide if the action should be audited based
	 * on whether the current task itself is being audited.
	 */
	return audit_seccomp(syscall, signr, action);
}

L
Linus Torvalds 已提交
601 602 603 604 605
/*
 * Secure computing mode 1 allows only read/write/exit/sigreturn.
 * To be fully secure this must be combined with rlimit
 * to limit the stack allocations too.
 */
606
static const int mode1_syscalls[] = {
L
Linus Torvalds 已提交
607 608 609 610
	__NR_seccomp_read, __NR_seccomp_write, __NR_seccomp_exit, __NR_seccomp_sigreturn,
	0, /* null terminated */
};

611
static void __secure_computing_strict(int this_syscall)
L
Linus Torvalds 已提交
612
{
613
	const int *syscall_whitelist = mode1_syscalls;
614
#ifdef CONFIG_COMPAT
615
	if (in_compat_syscall())
616
		syscall_whitelist = get_compat_mode1_syscalls();
617 618 619 620 621 622 623 624 625
#endif
	do {
		if (*syscall_whitelist == this_syscall)
			return;
	} while (*++syscall_whitelist);

#ifdef SECCOMP_DEBUG
	dump_stack();
#endif
626
	seccomp_log(this_syscall, SIGKILL, SECCOMP_RET_KILL_THREAD, true);
627 628 629 630 631 632 633 634
	do_exit(SIGKILL);
}

#ifndef CONFIG_HAVE_ARCH_SECCOMP_FILTER
void secure_computing_strict(int this_syscall)
{
	int mode = current->seccomp.mode;

635
	if (IS_ENABLED(CONFIG_CHECKPOINT_RESTORE) &&
636 637 638
	    unlikely(current->ptrace & PT_SUSPEND_SECCOMP))
		return;

639
	if (mode == SECCOMP_MODE_DISABLED)
640 641 642 643 644 645 646
		return;
	else if (mode == SECCOMP_MODE_STRICT)
		__secure_computing_strict(this_syscall);
	else
		BUG();
}
#else
647 648

#ifdef CONFIG_SECCOMP_FILTER
649 650
static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
			    const bool recheck_after_trace)
651 652
{
	u32 filter_ret, action;
653
	struct seccomp_filter *match = NULL;
654
	int data;
L
Linus Torvalds 已提交
655

656 657 658 659 660 661
	/*
	 * Make sure that any changes to mode from another thread have
	 * been seen after TIF_SECCOMP was seen.
	 */
	rmb();

662
	filter_ret = seccomp_run_filters(sd, &match);
663
	data = filter_ret & SECCOMP_RET_DATA;
664
	action = filter_ret & SECCOMP_RET_ACTION_FULL;
665 666 667

	switch (action) {
	case SECCOMP_RET_ERRNO:
668 669 670
		/* Set low-order bits as an errno, capped at MAX_ERRNO. */
		if (data > MAX_ERRNO)
			data = MAX_ERRNO;
671
		syscall_set_return_value(current, task_pt_regs(current),
672 673 674 675 676
					 -data, 0);
		goto skip;

	case SECCOMP_RET_TRAP:
		/* Show the handler the original registers. */
677
		syscall_rollback(current, task_pt_regs(current));
678 679 680 681 682
		/* Let the filter pass back 16 bits of data. */
		seccomp_send_sigsys(this_syscall, data);
		goto skip;

	case SECCOMP_RET_TRACE:
683 684 685 686
		/* We've been put in this state by the ptracer already. */
		if (recheck_after_trace)
			return 0;

K
Kees Cook 已提交
687 688 689 690 691 692 693 694 695 696 697 698
		/* ENOSYS these calls if there is no tracer attached. */
		if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) {
			syscall_set_return_value(current,
						 task_pt_regs(current),
						 -ENOSYS, 0);
			goto skip;
		}

		/* Allow the BPF to provide the event message */
		ptrace_event(PTRACE_EVENT_SECCOMP, data);
		/*
		 * The delivery of a fatal signal during event
699 700 701 702 703 704 705
		 * notification may silently skip tracer notification,
		 * which could leave us with a potentially unmodified
		 * syscall that the tracer would have liked to have
		 * changed. Since the process is about to die, we just
		 * force the syscall to be skipped and let the signal
		 * kill the process and correctly handle any tracer exit
		 * notifications.
K
Kees Cook 已提交
706 707
		 */
		if (fatal_signal_pending(current))
708
			goto skip;
K
Kees Cook 已提交
709 710 711 712 713
		/* Check if the tracer forced the syscall to be skipped. */
		this_syscall = syscall_get_nr(current, task_pt_regs(current));
		if (this_syscall < 0)
			goto skip;

714 715 716 717 718 719 720 721 722
		/*
		 * Recheck the syscall, since it may have changed. This
		 * intentionally uses a NULL struct seccomp_data to force
		 * a reload of all registers. This does not goto skip since
		 * a skip would have already been reported.
		 */
		if (__seccomp_filter(this_syscall, NULL, true))
			return -1;

K
Kees Cook 已提交
723
		return 0;
724

725 726 727 728
	case SECCOMP_RET_LOG:
		seccomp_log(this_syscall, 0, action, true);
		return 0;

729
	case SECCOMP_RET_ALLOW:
730 731 732 733 734
		/*
		 * Note that the "match" filter will always be NULL for
		 * this action since SECCOMP_RET_ALLOW is the starting
		 * state in seccomp_run_filters().
		 */
K
Kees Cook 已提交
735
		return 0;
736

737
	case SECCOMP_RET_KILL_THREAD:
738
	case SECCOMP_RET_KILL_PROCESS:
K
Kees Cook 已提交
739
	default:
740
		seccomp_log(this_syscall, SIGSYS, action, true);
741
		/* Dump core only if this is the last remaining thread. */
742 743
		if (action == SECCOMP_RET_KILL_PROCESS ||
		    get_nr_threads(current) == 1) {
K
Kees Cook 已提交
744 745
			siginfo_t info;

746 747 748 749 750 751
			/* Show the original registers in the dump. */
			syscall_rollback(current, task_pt_regs(current));
			/* Trigger a manual coredump since do_exit skips it. */
			seccomp_init_siginfo(&info, this_syscall, data);
			do_coredump(&info);
		}
752 753 754 755
		if (action == SECCOMP_RET_KILL_PROCESS)
			do_group_exit(SIGSYS);
		else
			do_exit(SIGSYS);
756 757 758 759 760
	}

	unreachable();

skip:
761
	seccomp_log(this_syscall, 0, action, match ? match->log : false);
K
Kees Cook 已提交
762 763 764
	return -1;
}
#else
765 766
static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
			    const bool recheck_after_trace)
K
Kees Cook 已提交
767 768
{
	BUG();
769
}
L
Linus Torvalds 已提交
770
#endif
771

K
Kees Cook 已提交
772
int __secure_computing(const struct seccomp_data *sd)
773 774
{
	int mode = current->seccomp.mode;
K
Kees Cook 已提交
775
	int this_syscall;
776

777
	if (IS_ENABLED(CONFIG_CHECKPOINT_RESTORE) &&
778
	    unlikely(current->ptrace & PT_SUSPEND_SECCOMP))
K
Kees Cook 已提交
779 780 781 782
		return 0;

	this_syscall = sd ? sd->nr :
		syscall_get_nr(current, task_pt_regs(current));
783

784
	switch (mode) {
785
	case SECCOMP_MODE_STRICT:
786
		__secure_computing_strict(this_syscall);  /* may call do_exit */
K
Kees Cook 已提交
787
		return 0;
788
	case SECCOMP_MODE_FILTER:
789
		return __seccomp_filter(this_syscall, sd, false);
L
Linus Torvalds 已提交
790 791 792
	default:
		BUG();
	}
793
}
794
#endif /* CONFIG_HAVE_ARCH_SECCOMP_FILTER */
795 796 797 798 799 800

long prctl_get_seccomp(void)
{
	return current->seccomp.mode;
}

801
/**
K
Kees Cook 已提交
802
 * seccomp_set_mode_strict: internal function for setting strict seccomp
803 804 805 806 807
 *
 * Once current->seccomp.mode is non-zero, it may not be changed.
 *
 * Returns 0 on success or -EINVAL on failure.
 */
K
Kees Cook 已提交
808
static long seccomp_set_mode_strict(void)
809
{
K
Kees Cook 已提交
810
	const unsigned long seccomp_mode = SECCOMP_MODE_STRICT;
811
	long ret = -EINVAL;
812

K
Kees Cook 已提交
813 814
	spin_lock_irq(&current->sighand->siglock);

815
	if (!seccomp_may_assign_mode(seccomp_mode))
816 817
		goto out;

818
#ifdef TIF_NOTSC
K
Kees Cook 已提交
819
	disable_TSC();
820
#endif
821
	seccomp_assign_mode(current, seccomp_mode);
K
Kees Cook 已提交
822 823 824
	ret = 0;

out:
K
Kees Cook 已提交
825
	spin_unlock_irq(&current->sighand->siglock);
K
Kees Cook 已提交
826 827 828 829

	return ret;
}

830
#ifdef CONFIG_SECCOMP_FILTER
K
Kees Cook 已提交
831 832
/**
 * seccomp_set_mode_filter: internal function for setting seccomp filter
K
Kees Cook 已提交
833
 * @flags:  flags to change filter behavior
K
Kees Cook 已提交
834 835 836 837 838 839 840 841 842 843
 * @filter: struct sock_fprog containing filter
 *
 * This function may be called repeatedly to install additional filters.
 * Every filter successfully installed will be evaluated (in reverse order)
 * for each system call the task makes.
 *
 * Once current->seccomp.mode is non-zero, it may not be changed.
 *
 * Returns 0 on success or -EINVAL on failure.
 */
K
Kees Cook 已提交
844 845
static long seccomp_set_mode_filter(unsigned int flags,
				    const char __user *filter)
K
Kees Cook 已提交
846 847
{
	const unsigned long seccomp_mode = SECCOMP_MODE_FILTER;
848
	struct seccomp_filter *prepared = NULL;
K
Kees Cook 已提交
849 850
	long ret = -EINVAL;

K
Kees Cook 已提交
851
	/* Validate flags. */
852
	if (flags & ~SECCOMP_FILTER_FLAG_MASK)
K
Kees Cook 已提交
853
		return -EINVAL;
K
Kees Cook 已提交
854

855 856 857 858 859
	/* Prepare the new filter before holding any locks. */
	prepared = seccomp_prepare_user_filter(filter);
	if (IS_ERR(prepared))
		return PTR_ERR(prepared);

860 861 862 863 864 865 866 867
	/*
	 * Make sure we cannot change seccomp or nnp state via TSYNC
	 * while another thread is in the middle of calling exec.
	 */
	if (flags & SECCOMP_FILTER_FLAG_TSYNC &&
	    mutex_lock_killable(&current->signal->cred_guard_mutex))
		goto out_free;

K
Kees Cook 已提交
868 869
	spin_lock_irq(&current->sighand->siglock);

K
Kees Cook 已提交
870 871 872
	if (!seccomp_may_assign_mode(seccomp_mode))
		goto out;

873
	ret = seccomp_attach_filter(flags, prepared);
K
Kees Cook 已提交
874
	if (ret)
875
		goto out;
876 877
	/* Do not free the successfully attached filter. */
	prepared = NULL;
878

879
	seccomp_assign_mode(current, seccomp_mode);
880
out:
K
Kees Cook 已提交
881
	spin_unlock_irq(&current->sighand->siglock);
882 883 884
	if (flags & SECCOMP_FILTER_FLAG_TSYNC)
		mutex_unlock(&current->signal->cred_guard_mutex);
out_free:
885
	seccomp_filter_free(prepared);
886 887
	return ret;
}
K
Kees Cook 已提交
888
#else
K
Kees Cook 已提交
889 890
static inline long seccomp_set_mode_filter(unsigned int flags,
					   const char __user *filter)
K
Kees Cook 已提交
891 892 893 894
{
	return -EINVAL;
}
#endif
895

896 897 898 899 900 901 902 903
static long seccomp_get_action_avail(const char __user *uaction)
{
	u32 action;

	if (copy_from_user(&action, uaction, sizeof(action)))
		return -EFAULT;

	switch (action) {
904
	case SECCOMP_RET_KILL_PROCESS:
905
	case SECCOMP_RET_KILL_THREAD:
906 907 908
	case SECCOMP_RET_TRAP:
	case SECCOMP_RET_ERRNO:
	case SECCOMP_RET_TRACE:
909
	case SECCOMP_RET_LOG:
910 911 912 913 914 915 916 917 918
	case SECCOMP_RET_ALLOW:
		break;
	default:
		return -EOPNOTSUPP;
	}

	return 0;
}

K
Kees Cook 已提交
919 920 921 922 923 924 925 926 927 928 929
/* Common entry point for both prctl and syscall. */
static long do_seccomp(unsigned int op, unsigned int flags,
		       const char __user *uargs)
{
	switch (op) {
	case SECCOMP_SET_MODE_STRICT:
		if (flags != 0 || uargs != NULL)
			return -EINVAL;
		return seccomp_set_mode_strict();
	case SECCOMP_SET_MODE_FILTER:
		return seccomp_set_mode_filter(flags, uargs);
930 931 932 933 934
	case SECCOMP_GET_ACTION_AVAIL:
		if (flags != 0)
			return -EINVAL;

		return seccomp_get_action_avail(uargs);
K
Kees Cook 已提交
935 936 937 938 939 940 941 942 943 944 945
	default:
		return -EINVAL;
	}
}

SYSCALL_DEFINE3(seccomp, unsigned int, op, unsigned int, flags,
			 const char __user *, uargs)
{
	return do_seccomp(op, flags, uargs);
}

946 947 948 949 950 951 952 953 954
/**
 * prctl_set_seccomp: configures current->seccomp.mode
 * @seccomp_mode: requested mode to use
 * @filter: optional struct sock_fprog for use with SECCOMP_MODE_FILTER
 *
 * Returns 0 on success or -EINVAL on failure.
 */
long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter)
{
K
Kees Cook 已提交
955 956 957
	unsigned int op;
	char __user *uargs;

K
Kees Cook 已提交
958 959
	switch (seccomp_mode) {
	case SECCOMP_MODE_STRICT:
K
Kees Cook 已提交
960 961 962 963 964 965 966 967
		op = SECCOMP_SET_MODE_STRICT;
		/*
		 * Setting strict mode through prctl always ignored filter,
		 * so make sure it is always NULL here to pass the internal
		 * check in do_seccomp().
		 */
		uargs = NULL;
		break;
K
Kees Cook 已提交
968
	case SECCOMP_MODE_FILTER:
K
Kees Cook 已提交
969 970 971
		op = SECCOMP_SET_MODE_FILTER;
		uargs = filter;
		break;
K
Kees Cook 已提交
972 973 974
	default:
		return -EINVAL;
	}
K
Kees Cook 已提交
975 976 977

	/* prctl interface doesn't have flags, so they are always zero. */
	return do_seccomp(op, 0, uargs);
978
}
979 980

#if defined(CONFIG_SECCOMP_FILTER) && defined(CONFIG_CHECKPOINT_RESTORE)
981 982
static struct seccomp_filter *get_nth_filter(struct task_struct *task,
					     unsigned long filter_off)
983
{
984 985
	struct seccomp_filter *orig, *filter;
	unsigned long count;
986

987 988 989 990
	/*
	 * Note: this is only correct because the caller should be the (ptrace)
	 * tracer of the task, otherwise lock_task_sighand is needed.
	 */
991
	spin_lock_irq(&task->sighand->siglock);
992

993
	if (task->seccomp.mode != SECCOMP_MODE_FILTER) {
994 995
		spin_unlock_irq(&task->sighand->siglock);
		return ERR_PTR(-EINVAL);
996 997
	}

998 999 1000 1001 1002 1003
	orig = task->seccomp.filter;
	__get_seccomp_filter(orig);
	spin_unlock_irq(&task->sighand->siglock);

	count = 0;
	for (filter = orig; filter; filter = filter->prev)
1004 1005 1006
		count++;

	if (filter_off >= count) {
1007
		filter = ERR_PTR(-ENOENT);
1008 1009 1010
		goto out;
	}

1011 1012
	count -= filter_off;
	for (filter = orig; filter && count > 1; filter = filter->prev)
1013 1014 1015
		count--;

	if (WARN_ON(count != 1 || !filter)) {
1016
		filter = ERR_PTR(-ENOENT);
1017 1018 1019
		goto out;
	}

1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
	__get_seccomp_filter(filter);

out:
	__put_seccomp_filter(orig);
	return filter;
}

long seccomp_get_filter(struct task_struct *task, unsigned long filter_off,
			void __user *data)
{
	struct seccomp_filter *filter;
	struct sock_fprog_kern *fprog;
	long ret;

	if (!capable(CAP_SYS_ADMIN) ||
	    current->seccomp.mode != SECCOMP_MODE_DISABLED) {
		return -EACCES;
	}

	filter = get_nth_filter(task, filter_off);
	if (IS_ERR(filter))
		return PTR_ERR(filter);

1043 1044
	fprog = filter->prog->orig_prog;
	if (!fprog) {
M
Mickaël Salaün 已提交
1045
		/* This must be a new non-cBPF filter, since we save
1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
		 * every cBPF filter's orig_prog above when
		 * CONFIG_CHECKPOINT_RESTORE is enabled.
		 */
		ret = -EMEDIUMTYPE;
		goto out;
	}

	ret = fprog->len;
	if (!data)
		goto out;

	if (copy_to_user(data, fprog->filter, bpf_classic_proglen(fprog)))
		ret = -EFAULT;

out:
1061
	__put_seccomp_filter(filter);
1062 1063
	return ret;
}
1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078

long seccomp_get_metadata(struct task_struct *task,
			  unsigned long size, void __user *data)
{
	long ret;
	struct seccomp_filter *filter;
	struct seccomp_metadata kmd = {};

	if (!capable(CAP_SYS_ADMIN) ||
	    current->seccomp.mode != SECCOMP_MODE_DISABLED) {
		return -EACCES;
	}

	size = min_t(unsigned long, size, sizeof(kmd));

1079 1080 1081 1082
	if (size < sizeof(kmd.filter_off))
		return -EINVAL;

	if (copy_from_user(&kmd.filter_off, data, sizeof(kmd.filter_off)))
1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098
		return -EFAULT;

	filter = get_nth_filter(task, kmd.filter_off);
	if (IS_ERR(filter))
		return PTR_ERR(filter);

	if (filter->log)
		kmd.flags |= SECCOMP_FILTER_FLAG_LOG;

	ret = size;
	if (copy_to_user(data, &kmd, size))
		ret = -EFAULT;

	__put_seccomp_filter(filter);
	return ret;
}
1099
#endif
1100 1101 1102 1103

#ifdef CONFIG_SYSCTL

/* Human readable action names for friendly sysctl interaction */
1104
#define SECCOMP_RET_KILL_PROCESS_NAME	"kill_process"
1105
#define SECCOMP_RET_KILL_THREAD_NAME	"kill_thread"
1106 1107 1108
#define SECCOMP_RET_TRAP_NAME		"trap"
#define SECCOMP_RET_ERRNO_NAME		"errno"
#define SECCOMP_RET_TRACE_NAME		"trace"
1109
#define SECCOMP_RET_LOG_NAME		"log"
1110 1111
#define SECCOMP_RET_ALLOW_NAME		"allow"

1112
static const char seccomp_actions_avail[] =
1113
				SECCOMP_RET_KILL_PROCESS_NAME	" "
1114 1115 1116 1117 1118 1119
				SECCOMP_RET_KILL_THREAD_NAME	" "
				SECCOMP_RET_TRAP_NAME		" "
				SECCOMP_RET_ERRNO_NAME		" "
				SECCOMP_RET_TRACE_NAME		" "
				SECCOMP_RET_LOG_NAME		" "
				SECCOMP_RET_ALLOW_NAME;
1120

1121 1122 1123 1124 1125 1126
struct seccomp_log_name {
	u32		log;
	const char	*name;
};

static const struct seccomp_log_name seccomp_log_names[] = {
1127
	{ SECCOMP_LOG_KILL_PROCESS, SECCOMP_RET_KILL_PROCESS_NAME },
1128
	{ SECCOMP_LOG_KILL_THREAD, SECCOMP_RET_KILL_THREAD_NAME },
1129 1130 1131
	{ SECCOMP_LOG_TRAP, SECCOMP_RET_TRAP_NAME },
	{ SECCOMP_LOG_ERRNO, SECCOMP_RET_ERRNO_NAME },
	{ SECCOMP_LOG_TRACE, SECCOMP_RET_TRACE_NAME },
1132
	{ SECCOMP_LOG_LOG, SECCOMP_RET_LOG_NAME },
1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243
	{ SECCOMP_LOG_ALLOW, SECCOMP_RET_ALLOW_NAME },
	{ }
};

static bool seccomp_names_from_actions_logged(char *names, size_t size,
					      u32 actions_logged)
{
	const struct seccomp_log_name *cur;
	bool append_space = false;

	for (cur = seccomp_log_names; cur->name && size; cur++) {
		ssize_t ret;

		if (!(actions_logged & cur->log))
			continue;

		if (append_space) {
			ret = strscpy(names, " ", size);
			if (ret < 0)
				return false;

			names += ret;
			size -= ret;
		} else
			append_space = true;

		ret = strscpy(names, cur->name, size);
		if (ret < 0)
			return false;

		names += ret;
		size -= ret;
	}

	return true;
}

static bool seccomp_action_logged_from_name(u32 *action_logged,
					    const char *name)
{
	const struct seccomp_log_name *cur;

	for (cur = seccomp_log_names; cur->name; cur++) {
		if (!strcmp(cur->name, name)) {
			*action_logged = cur->log;
			return true;
		}
	}

	return false;
}

static bool seccomp_actions_logged_from_names(u32 *actions_logged, char *names)
{
	char *name;

	*actions_logged = 0;
	while ((name = strsep(&names, " ")) && *name) {
		u32 action_logged = 0;

		if (!seccomp_action_logged_from_name(&action_logged, name))
			return false;

		*actions_logged |= action_logged;
	}

	return true;
}

static int seccomp_actions_logged_handler(struct ctl_table *ro_table, int write,
					  void __user *buffer, size_t *lenp,
					  loff_t *ppos)
{
	char names[sizeof(seccomp_actions_avail)];
	struct ctl_table table;
	int ret;

	if (write && !capable(CAP_SYS_ADMIN))
		return -EPERM;

	memset(names, 0, sizeof(names));

	if (!write) {
		if (!seccomp_names_from_actions_logged(names, sizeof(names),
						       seccomp_actions_logged))
			return -EINVAL;
	}

	table = *ro_table;
	table.data = names;
	table.maxlen = sizeof(names);
	ret = proc_dostring(&table, write, buffer, lenp, ppos);
	if (ret)
		return ret;

	if (write) {
		u32 actions_logged;

		if (!seccomp_actions_logged_from_names(&actions_logged,
						       table.data))
			return -EINVAL;

		if (actions_logged & SECCOMP_LOG_ALLOW)
			return -EINVAL;

		seccomp_actions_logged = actions_logged;
	}

	return 0;
}

1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257
static struct ctl_path seccomp_sysctl_path[] = {
	{ .procname = "kernel", },
	{ .procname = "seccomp", },
	{ }
};

static struct ctl_table seccomp_sysctl_table[] = {
	{
		.procname	= "actions_avail",
		.data		= (void *) &seccomp_actions_avail,
		.maxlen		= sizeof(seccomp_actions_avail),
		.mode		= 0444,
		.proc_handler	= proc_dostring,
	},
1258 1259 1260 1261 1262
	{
		.procname	= "actions_logged",
		.mode		= 0644,
		.proc_handler	= seccomp_actions_logged_handler,
	},
1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281
	{ }
};

static int __init seccomp_sysctl_init(void)
{
	struct ctl_table_header *hdr;

	hdr = register_sysctl_paths(seccomp_sysctl_path, seccomp_sysctl_table);
	if (!hdr)
		pr_warn("seccomp: sysctl registration failed\n");
	else
		kmemleak_not_leak(hdr);

	return 0;
}

device_initcall(seccomp_sysctl_init)

#endif /* CONFIG_SYSCTL */