2 * Seccomp System Interfaces
4 * Copyright (c) 2014 Red Hat <pmoore@redhat.com>
5 * Author: Paul Moore <paul@paul-moore.com>
9 * This library is free software; you can redistribute it and/or modify it
10 * under the terms of version 2.1 of the GNU Lesser General Public License as
11 * published by the Free Software Foundation.
13 * This library is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this library; if not, see <http://www.gnu.org/licenses>.
24 #include <sys/prctl.h>
36 /* NOTE: the seccomp syscall whitelist is currently disabled for testing
37 * purposes, but unless we can verify all of the supported ABIs before
38 * our next release we may have to enable the whitelist */
39 #define SYSCALL_WHITELIST_ENABLE 0
41 static int _nr_seccomp
= -1;
42 static int _support_seccomp_syscall
= -1;
45 * Check to see if the seccomp() syscall is supported
47 * This function attempts to see if the system supports the seccomp() syscall.
48 * Unfortunately, there are a few reasons why this check may fail, including
49 * a previously loaded seccomp filter, so it is hard to say for certain.
50 * Return one if the syscall is supported, zero otherwise.
53 int sys_chk_seccomp_syscall(void)
58 /* NOTE: it is reasonably safe to assume that we should be able to call
59 * seccomp() when the caller first starts, but we can't rely on
60 * it later so we need to cache our findings for use later */
61 if (_support_seccomp_syscall
>= 0)
62 return _support_seccomp_syscall
;
64 #if SYSCALL_WHITELIST_ENABLE
65 /* architecture whitelist */
66 switch (arch_def_native
->token
) {
67 case SCMP_ARCH_X86_64
:
69 case SCMP_ARCH_AARCH64
:
71 case SCMP_ARCH_PPC64LE
:
80 nr_seccomp
= arch_syscall_resolve_name(arch_def_native
, "seccomp");
84 /* this is an invalid call because the second argument is non-zero, but
85 * depending on the errno value of ENOSYS or EINVAL we can guess if the
86 * seccomp() syscal is supported or not */
87 rc
= syscall(nr_seccomp
, SECCOMP_SET_MODE_STRICT
, 1, NULL
);
88 if (rc
< 0 && errno
== EINVAL
)
92 _support_seccomp_syscall
= 0;
95 _nr_seccomp
= nr_seccomp
;
96 _support_seccomp_syscall
= 1;
101 * Check to see if a seccomp() flag is supported
102 * @param flag the seccomp() flag
104 * This function checks to see if a seccomp() flag is supported by the system.
105 * If the flag is supported one is returned, zero if unsupported, negative
109 int sys_chk_seccomp_flag(int flag
)
112 case SECCOMP_FILTER_FLAG_TSYNC
:
113 return sys_chk_seccomp_syscall();
120 * Loads the filter into the kernel
121 * @param col the filter collection
123 * This function loads the given seccomp filter context into the kernel. If
124 * the filter was loaded correctly, the kernel will be enforcing the filter
125 * when this function returns. Returns zero on success, negative values on
129 int sys_filter_load(const struct db_filter_col
*col
)
132 struct bpf_program
*prgm
= NULL
;
134 prgm
= gen_bpf_generate(col
);
138 /* attempt to set NO_NEW_PRIVS */
139 if (col
->attr
.nnp_enable
) {
140 rc
= prctl(PR_SET_NO_NEW_PRIVS
, 1, 0, 0, 0);
142 goto filter_load_out
;
145 /* load the filter into the kernel */
146 if (sys_chk_seccomp_syscall() == 1) {
148 if (col
->attr
.tsync_enable
)
149 flgs
= SECCOMP_FILTER_FLAG_TSYNC
;
150 rc
= syscall(_nr_seccomp
, SECCOMP_SET_MODE_FILTER
, flgs
, prgm
);
151 if (rc
> 0 && col
->attr
.tsync_enable
)
152 /* always return -ESRCH if we fail to sync threads */
155 rc
= prctl(PR_SET_SECCOMP
, SECCOMP_MODE_FILTER
, prgm
);
158 /* cleanup and return */
159 gen_bpf_release(prgm
);