Skip to content

Commit

Permalink
seccomp: fix type mismatch when parsing syscall arguments filters
Browse files Browse the repository at this point in the history
Specifier %lli was insufficient for the type uint64_t, all values
between 2^63-1 and 2^64-1 were silently converted to 2^63-1.

We can't use %llu since it doesn't handle hexadecimal. Instead, we
parse the values as strings and then use strtoull(3).

Signed-off-by: Felix Abecassis <fabecassis@nvidia.com>
  • Loading branch information
flx42 committed May 24, 2018
1 parent 30adf86 commit eacebcc
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 2 deletions.
17 changes: 15 additions & 2 deletions src/lxc/seccomp.c
Expand Up @@ -32,6 +32,7 @@
#include "config.h"
#include "log.h"
#include "lxcseccomp.h"
#include "utils.h"

lxc_log_define(lxc_seccomp, lxc);

Expand Down Expand Up @@ -180,20 +181,32 @@ static int get_seccomp_arg_value(char *key, struct v2_rule_args *rule_args)
uint64_t mask = 0;
enum scmp_compare op = 0;
uint32_t index = 0;
char s[31] = {0};
char s[31] = {0}, v[24] = {0}, m[24] = {0};
char *tmp = NULL;

tmp = strchr(key, '[');
if (!tmp) {
ERROR("Failed to interpret args");
return -1;
}
ret = sscanf(tmp, "[%i,%lli,%30[^0-9^,],%lli", &index, (long long unsigned int *)&value, s, (long long unsigned int *)&mask);
ret = sscanf(tmp, "[%i,%23[^,],%30[^0-9^,],%23[^,]", &index, v, s, m);
if ((ret != 3 && ret != 4) || index >= 6) {
ERROR("Failed to interpret args value");
return -1;
}

ret = lxc_safe_uint64(v, &value);
if (ret < 0) {
ERROR("Invalid argument value");
return -1;
}

ret = lxc_safe_uint64(v, &mask);

This comment has been minimized.

Copy link
@flx42

flx42 May 24, 2018

Author Contributor

Oh well, I clearly messed up here, should be m.
Sorry @brauner :(

This comment has been minimized.

Copy link
@brauner

brauner May 24, 2018

Member

I saw, I already have a fix sitting in my #2347 branch. :)

This comment has been minimized.

Copy link
@flx42

flx42 May 24, 2018

Author Contributor

Should not have doubted you :)

if (ret < 0) {
ERROR("Invalid argument mask");
return -1;
}

op = parse_v2_rule_op(s);
if (op == _SCMP_CMP_MAX) {
ERROR("Failed to interpret args operator value");
Expand Down
23 changes: 23 additions & 0 deletions src/lxc/utils.c
Expand Up @@ -1958,6 +1958,29 @@ int lxc_safe_ulong(const char *numstr, unsigned long *converted)
return 0;
}

int lxc_safe_uint64(const char *numstr, uint64_t *converted)
{
char *err = NULL;
uint64_t u;

while (isspace(*numstr))
numstr++;

if (*numstr == '-')
return -EINVAL;

errno = 0;
u = strtoull(numstr, &err, 0);
if (errno == ERANGE && u == ULLONG_MAX)
return -ERANGE;

if (err == numstr || *err != '\0')
return -EINVAL;

*converted = u;
return 0;
}

int lxc_safe_int(const char *numstr, int *converted)
{
char *err = NULL;
Expand Down
1 change: 1 addition & 0 deletions src/lxc/utils.h
Expand Up @@ -530,6 +530,7 @@ extern int lxc_safe_int(const char *numstr, int *converted);
extern int lxc_safe_long(const char *numstr, long int *converted);
extern int lxc_safe_long_long(const char *numstr, long long int *converted);
extern int lxc_safe_ulong(const char *numstr, unsigned long *converted);
extern int lxc_safe_uint64(const char *numstr, uint64_t *converted);
/* Handles B, kb, MB, GB. Detects overflows and reports -ERANGE. */
extern int parse_byte_size_string(const char *s, int64_t *converted);

Expand Down

0 comments on commit eacebcc

Please sign in to comment.