-
Notifications
You must be signed in to change notification settings - Fork 289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
container: cache the seccomp generated bpf #1035
Changes from 5 commits
0cffffe
81d3b16
dd310aa
6861b2a
a2de8fb
7a66ccc
8cfcc8f
74d097b
3ebaba3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,10 @@ | |
#include <sys/stat.h> | ||
#include <sys/mman.h> | ||
|
||
#if HAVE_GCRYPT | ||
# include <gcrypt.h> | ||
#endif | ||
|
||
#if HAVE_STDATOMIC_H | ||
# include <stdatomic.h> | ||
#else | ||
|
@@ -340,6 +344,101 @@ seccomp_action_supports_errno (const char *action) | |
|| strcmp (action, "SCMP_ACT_TRACE") == 0; | ||
} | ||
|
||
static int | ||
calculate_seccomp_checksum (libcrun_container_t *container, unsigned int seccomp_gen_options, seccomp_checksum_t out, libcrun_error_t *err) | ||
{ | ||
#if HAVE_GCRYPT | ||
runtime_spec_schema_config_linux_seccomp *seccomp; | ||
gcry_error_t gcrypt_err; | ||
unsigned char *res; | ||
gcry_md_hd_t hd; | ||
size_t i; | ||
|
||
# define PROCESS_STRING(X) \ | ||
do \ | ||
{ \ | ||
if (X) \ | ||
{ \ | ||
gcry_md_write (hd, (X), strlen (X)); \ | ||
} \ | ||
} while (0) | ||
# define PROCESS_DATA(X) \ | ||
do \ | ||
{ \ | ||
gcry_md_write (hd, &(X), sizeof (X)); \ | ||
} while (0) | ||
|
||
out[0] = 0; | ||
|
||
if (container == NULL || container->container_def == NULL || container->container_def->linux == NULL) | ||
return 0; | ||
|
||
seccomp = container->container_def->linux->seccomp; | ||
if (seccomp == NULL) | ||
return 0; | ||
|
||
gcrypt_err = gcry_md_open (&hd, GCRY_MD_SHA256, 0); | ||
if (gcrypt_err) | ||
return crun_make_error (err, EINVAL, "internal libgcrypt error: %s", gcry_strerror (gcrypt_err)); | ||
|
||
PROCESS_STRING (PACKAGE_VERSION); | ||
|
||
# ifdef HAVE_SECCOMP | ||
{ | ||
const struct scmp_version *version = seccomp_version (); | ||
|
||
PROCESS_DATA (version->major); | ||
PROCESS_DATA (version->minor); | ||
PROCESS_DATA (version->micro); | ||
} | ||
# endif | ||
|
||
PROCESS_DATA (seccomp_gen_options); | ||
|
||
PROCESS_STRING (seccomp->default_action); | ||
for (i = 0; i < seccomp->flags_len; i++) | ||
PROCESS_STRING (seccomp->flags[i]); | ||
for (i = 0; i < seccomp->architectures_len; i++) | ||
PROCESS_STRING (seccomp->architectures[i]); | ||
for (i = 0; i < seccomp->syscalls_len; i++) | ||
{ | ||
size_t j; | ||
|
||
if (seccomp->syscalls[i]->action) | ||
PROCESS_STRING (seccomp->syscalls[i]->action); | ||
for (j = 0; j < seccomp->syscalls[i]->names_len; j++) | ||
PROCESS_STRING (seccomp->syscalls[i]->names[j]); | ||
for (j = 0; j < seccomp->syscalls[i]->args_len; j++) | ||
{ | ||
if (seccomp->syscalls[i]->args[j]->index_present) | ||
PROCESS_DATA (seccomp->syscalls[i]->args[j]->index); | ||
if (seccomp->syscalls[i]->args[j]->value_present) | ||
PROCESS_DATA (seccomp->syscalls[i]->args[j]->value); | ||
if (seccomp->syscalls[i]->args[j]->value_two_present) | ||
PROCESS_DATA (seccomp->syscalls[i]->args[j]->value_two); | ||
PROCESS_STRING (seccomp->syscalls[i]->args[j]->op); | ||
} | ||
} | ||
|
||
res = gcry_md_read (hd, GCRY_MD_SHA256); | ||
for (i = 0; i < 32; i++) | ||
sprintf (&out[i * 2], "%02x", res[i]); | ||
out[64] = 0; | ||
|
||
gcry_md_close (hd); | ||
|
||
# undef PROCESS_STRING | ||
# undef PROCESS_DATA | ||
#else | ||
(void) container; | ||
(void) seccomp_gen_options; | ||
(void) out; | ||
(void) err; | ||
out[0] = 0; | ||
#endif | ||
return 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't fully analyzed this, but this not returning an error here, or in the early NULL checks for container->container_def->linux->seccomp scares me. It feels like we may accidentally rely on the output digest even though it is not written to. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the only caller of this function is
I'll make it clearer and use a different argument instead of relying on the checksum return value. |
||
} | ||
|
||
int | ||
libcrun_generate_seccomp (libcrun_container_t *container, int outfd, unsigned int options, libcrun_error_t *err) | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this is enough, or if we also want to hash the current architecture? Say we seccomp->archtetures is ["i386"]. Will this give the same result when run on a i386 arch and a x86_64 arch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed, better be safe. Would hashing the result of
uname(2)
be enough?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pushed a new version where we also hash uname(2)