Skip to content

Commit fefabff

Browse files
committed
seccomp: honor seccomp flags
now the OCI runtime specs support to specify seccomp flags to use with the seccomp(2) syscall. The accepted options are: - SECCOMP_FILTER_FLAG_TSYNC - SECCOMP_FILTER_FLAG_SPEC_ALLOW - SECCOMP_FILTER_FLAG_LOG If there is no selection for the flags to use (i.e. there is no seccomp->flags specified), a default configuration is used: SECCOMP_FILTER_FLAG_LOG and SECCOMP_FILTER_FLAG_SPEC_ALLOW. From the man page: SECCOMP_FILTER_FLAG_LOG (since Linux 4.14) All filter return actions except SECCOMP_RET_ALLOW should be logged. An administrator may override this filter flag by preventing specific actions from being logged via the /proc/sys/kernel/seccomp/actions_logged file. SECCOMP_FILTER_FLAG_SPEC_ALLOW (since Linux 4.17) Disable Speculative Store Bypass mitigation. Signed-off-by: Giuseppe Scrivano <[email protected]>
1 parent 5cb7481 commit fefabff

File tree

3 files changed

+72
-12
lines changed

3 files changed

+72
-12
lines changed

src/libcrun/container.c

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,16 @@ container_entrypoint_init (void *args, const char *notify_socket,
540540

541541
if (def->process && !def->process->no_new_privileges)
542542
{
543-
ret = libcrun_generate_and_load_seccomp (entrypoint_args->container, entrypoint_args->seccomp_fd, err);
543+
char **seccomp_flags = NULL;
544+
size_t seccomp_flags_len = 0;
545+
546+
if (def->linux && def->linux->seccomp)
547+
{
548+
seccomp_flags = def->linux->seccomp->flags;
549+
seccomp_flags_len = def->linux->seccomp->flags_len;
550+
}
551+
552+
ret = libcrun_generate_and_load_seccomp (entrypoint_args->container, entrypoint_args->seccomp_fd, seccomp_flags, seccomp_flags_len, err);
544553
if (UNLIKELY (ret < 0))
545554
return ret;
546555
}
@@ -656,7 +665,16 @@ container_entrypoint (void *args, const char *notify_socket,
656665

657666
if (def->process && def->process->no_new_privileges)
658667
{
659-
ret = libcrun_generate_and_load_seccomp (entrypoint_args->container, entrypoint_args->seccomp_fd, err);
668+
char **seccomp_flags = NULL;
669+
size_t seccomp_flags_len = 0;
670+
671+
if (def->linux && def->linux->seccomp)
672+
{
673+
seccomp_flags = def->linux->seccomp->flags;
674+
seccomp_flags_len = def->linux->seccomp->flags_len;
675+
}
676+
677+
ret = libcrun_generate_and_load_seccomp (entrypoint_args->container, entrypoint_args->seccomp_fd, seccomp_flags, seccomp_flags_len, err);
660678
if (UNLIKELY (ret < 0))
661679
return ret;
662680
}
@@ -1871,6 +1889,8 @@ libcrun_container_exec (libcrun_context_t *context, const char *id, oci_containe
18711889
gid_t container_gid = process->user ? process->user->gid : 0;
18721890
const char *cwd;
18731891
oci_container_process_capabilities *capabilities = NULL;
1892+
char **seccomp_flags = NULL;
1893+
size_t seccomp_flags_len = 0;
18741894

18751895
close (pipefd0);
18761896
pipefd0 = -1;
@@ -1893,9 +1913,15 @@ libcrun_container_exec (libcrun_context_t *context, const char *id, oci_containe
18931913
libcrun_fail_with_error ((*err)->status, "%s", (*err)->msg);
18941914
}
18951915

1916+
if (container->container_def->linux && container->container_def->linux->seccomp)
1917+
{
1918+
seccomp_flags = container->container_def->linux->seccomp->flags;
1919+
seccomp_flags_len = container->container_def->linux->seccomp->flags_len;
1920+
}
1921+
18961922
if (!process->no_new_privileges)
18971923
{
1898-
ret = libcrun_apply_seccomp (seccomp_fd, err);
1924+
ret = libcrun_apply_seccomp (seccomp_fd, seccomp_flags, seccomp_flags_len, err);
18991925
if (UNLIKELY (ret < 0))
19001926
return ret;
19011927
}
@@ -1938,7 +1964,7 @@ libcrun_container_exec (libcrun_context_t *context, const char *id, oci_containe
19381964

19391965
if (process->no_new_privileges)
19401966
{
1941-
ret = libcrun_apply_seccomp (seccomp_fd, err);
1967+
ret = libcrun_apply_seccomp (seccomp_fd, seccomp_flags, seccomp_flags_len, err);
19421968
if (UNLIKELY (ret < 0))
19431969
return ret;
19441970
}

src/libcrun/seccomp.c

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@
3838
#include <linux/seccomp.h>
3939
#include <linux/filter.h>
4040
#include <sys/prctl.h>
41+
#include <sys/syscall.h>
42+
43+
static int
44+
syscall_seccomp (unsigned int operation, unsigned int flags, void *args)
45+
{
46+
return (int) syscall (__NR_seccomp, operation, flags, args);
47+
}
4148

4249
unsigned long
4350
get_seccomp_operator (const char *name, libcrun_error_t *err)
@@ -99,32 +106,59 @@ cleanup_seccompp (void *p)
99106
#define cleanup_seccomp __attribute__((cleanup (cleanup_seccompp)))
100107

101108
int
102-
libcrun_apply_seccomp (int infd, libcrun_error_t *err)
109+
libcrun_apply_seccomp (int infd, char **seccomp_flags, size_t seccomp_flags_len, libcrun_error_t *err)
103110
{
104111
int ret;
105112
struct sock_fprog seccomp_filter;
106113
cleanup_free char *bpf = NULL;
114+
unsigned int flags = 0;
107115
size_t len;
108116

109117
if (infd < 0)
110118
return 0;
111119

120+
121+
/* if no seccomp flag was specified use a sane default. */
122+
if (seccomp_flags == NULL)
123+
flags = SECCOMP_FILTER_FLAG_LOG|SECCOMP_FILTER_FLAG_SPEC_ALLOW;
124+
else
125+
{
126+
size_t i = 0;
127+
for (i = 0; i < seccomp_flags_len; i++)
128+
{
129+
if (strcmp (seccomp_flags[i], "SECCOMP_FILTER_FLAG_TSYNC") == 0)
130+
flags |= SECCOMP_FILTER_FLAG_TSYNC;
131+
else if (strcmp (seccomp_flags[i], "SECCOMP_FILTER_FLAG_SPEC_ALLOW") == 0)
132+
flags |= SECCOMP_FILTER_FLAG_SPEC_ALLOW;
133+
else if (strcmp (seccomp_flags[i], "SECCOMP_FILTER_FLAG_LOG") == 0)
134+
flags |= SECCOMP_FILTER_FLAG_LOG;
135+
else
136+
return crun_make_error (err, 0, "unknown seccomp option %s", seccomp_flags[i]);
137+
}
138+
}
139+
112140
ret = read_all_fd (infd, "seccomp.bpf", &bpf, &len, err);
113141
if (UNLIKELY (ret < 0))
114142
return ret;
115143

116144
seccomp_filter.len = len / 8;
117145
seccomp_filter.filter = (struct sock_filter *) bpf;
118146

119-
ret = prctl (PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &seccomp_filter);
147+
ret = syscall_seccomp (SECCOMP_SET_MODE_FILTER, flags, &seccomp_filter);
120148
if (UNLIKELY (ret < 0))
121-
return crun_make_error (err, errno, "prctl (PR_SET_SECCOMP)");
149+
{
150+
/* If any of the flags is not supported, try again without specifying them: */
151+
if (errno == EINVAL)
152+
ret = syscall_seccomp (SECCOMP_SET_MODE_FILTER, 0, &seccomp_filter);
153+
if (UNLIKELY (ret < 0))
154+
return crun_make_error (err, errno, "seccomp (SECCOMP_SET_MODE_FILTER)");
155+
}
122156

123157
return 0;
124158
}
125159

126160
int
127-
libcrun_generate_and_load_seccomp (libcrun_container_t *container, int outfd, libcrun_error_t *err)
161+
libcrun_generate_and_load_seccomp (libcrun_container_t *container, int outfd, char **flags, size_t flags_len, libcrun_error_t *err)
128162
{
129163
oci_container_linux_seccomp *seccomp = container->container_def->linux->seccomp;
130164
int ret;
@@ -233,8 +267,8 @@ libcrun_generate_and_load_seccomp (libcrun_container_t *container, int outfd, li
233267
return crun_make_error (err, 0, "seccomp_export_bpf");
234268
}
235269

236-
if (lseek (outfd, 0, SEEK_SET) == (off_t) -1)
270+
if (UNLIKELY (lseek (outfd, 0, SEEK_SET) == (off_t) -1))
237271
return crun_make_error (err, 0, "lseek");
238272

239-
return libcrun_apply_seccomp (outfd, err);
273+
return libcrun_apply_seccomp (outfd, flags, flags_len, err);
240274
}

src/libcrun/seccomp.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
# include <oci_runtime_spec.h>
2727
# include "container.h"
2828

29-
int libcrun_generate_and_load_seccomp (libcrun_container_t *container, int outfd, libcrun_error_t *err);
30-
int libcrun_apply_seccomp (int infd, libcrun_error_t *err);
29+
int libcrun_generate_and_load_seccomp (libcrun_container_t *container, int outfd, char **flags, size_t flags_len, libcrun_error_t *err);
30+
int libcrun_apply_seccomp (int infd, char **flags, size_t flags_len, libcrun_error_t *err);
3131

3232
#endif

0 commit comments

Comments
 (0)