Skip to content

Commit

Permalink
crun: check for integer overflow
Browse files Browse the repository at this point in the history
validate that the stroll returned value can fit into an integer.

Closes: containers#1604

Reported-by: Pavel Nekrasov <p.nekrasov@fobos-nt.ru>
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
  • Loading branch information
giuseppe committed Nov 14, 2024
1 parent 7063a7e commit 42d408e
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/create.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;

case OPTION_PRESERVE_FDS:
crun_context.preserve_fds = strtoul (argp_mandatory_argument (arg, state), NULL, 10);
crun_context.preserve_fds = parse_int_or_fail (argp_mandatory_argument (arg, state), "preserve-fds");
break;

case OPTION_NO_SUBREAPER:
Expand Down Expand Up @@ -166,7 +166,7 @@ crun_command_create (struct crun_global_arguments *global_args, int argc, char *
crun_context.bundle = bundle;
if (getenv ("LISTEN_FDS"))
{
crun_context.listen_fds = strtoll (getenv ("LISTEN_FDS"), NULL, 10);
crun_context.listen_fds = parse_int_or_fail (getenv ("LISTEN_FDS"), "LISTEN_FDS");
crun_context.preserve_fds += crun_context.listen_fds;
}

Expand Down
20 changes: 20 additions & 0 deletions src/crun.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include <argp.h>
#include <string.h>
#include <libgen.h>
#include <errno.h>
#include <limits.h>

#ifdef HAVE_DLOPEN
# include <dlfcn.h>
Expand Down Expand Up @@ -373,6 +375,24 @@ argp_mandatory_argument (char *arg, struct argp_state *state)
return state->argv[state->next++];
}

int
parse_int_or_fail (const char *str, const char *kind)
{
char *endptr = NULL;
long long l;

errno = 0;
l = strtoll (str, &endptr, 10);
if (errno != 0)
libcrun_fail_with_error (errno, "invalid value for `%s`", kind);
if (endptr != NULL && *endptr != '\0')
libcrun_fail_with_error (EINVAL, "invalid value for `%s`", kind);
if (l < INT_MIN || l > INT_MAX)
libcrun_fail_with_error (ERANGE, "invalid value for `%s`", kind);

return (int) l;
}

static struct argp argp = { options, parse_opt, args_doc, doc, NULL, NULL, NULL };

int ensure_cloned_binary (void);
Expand Down
1 change: 1 addition & 0 deletions src/crun.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ struct crun_global_arguments
};

char *argp_mandatory_argument (char *arg, struct argp_state *state);
int parse_int_or_fail (const char *str, const char *kind);
int init_libcrun_context (libcrun_context_t *con, const char *id, struct crun_global_arguments *glob,
libcrun_error_t *err);
void crun_assert_n_args (int n, int min, int max);
Expand Down
15 changes: 11 additions & 4 deletions src/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;

case OPTION_PRESERVE_FDS:
exec_options.preserve_fds = strtoul (argp_mandatory_argument (arg, state), NULL, 10);
exec_options.preserve_fds = parse_int_or_fail (argp_mandatory_argument (arg, state), "preserve-fds");
break;

case OPTION_CGROUP:
Expand Down Expand Up @@ -203,27 +203,34 @@ make_oci_process_user (const char *userspec)
{
runtime_spec_schema_config_schema_process_user *u;
char *endptr = NULL;
long long l;

if (userspec == NULL)
return NULL;

u = xmalloc0 (sizeof (runtime_spec_schema_config_schema_process_user));
errno = 0;
u->uid = strtol (userspec, &endptr, 10);
l = strtoll (userspec, &endptr, 10);
if (errno == ERANGE)
libcrun_fail_with_error (0, "invalid UID specified");
if (*endptr == '\0')
return u;
if (*endptr != ':')
libcrun_fail_with_error (0, "invalid USERSPEC specified");
if (l < INT_MIN || l > INT_MAX)
libcrun_fail_with_error (0, "invalid UID specified");

u->uid = (int) l;

errno = 0;
u->gid = strtol (endptr + 1, &endptr, 10);
l = strtoll (endptr + 1, &endptr, 10);
if (errno == ERANGE)
libcrun_fail_with_error (0, "invalid GID specified");
if (l < INT_MIN || l > INT_MAX)
libcrun_fail_with_error (0, "invalid GID specified");
if (*endptr != '\0')
libcrun_fail_with_error (0, "invalid USERSPEC specified");

u->gid = (int) l;
return u;
}

Expand Down
4 changes: 2 additions & 2 deletions src/run.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;

case OPTION_PRESERVE_FDS:
crun_context.preserve_fds = strtoll (argp_mandatory_argument (arg, state), NULL, 10);
crun_context.preserve_fds = parse_int_or_fail (argp_mandatory_argument (arg, state), "preserve-fds");
break;

case OPTION_NO_SUBREAPER:
Expand Down Expand Up @@ -177,7 +177,7 @@ crun_command_run (struct crun_global_arguments *global_args, int argc, char **ar
crun_context.bundle = bundle;
if (getenv ("LISTEN_FDS"))
{
crun_context.listen_fds = strtoll (getenv ("LISTEN_FDS"), NULL, 10);
crun_context.listen_fds = parse_int_or_fail (getenv ("LISTEN_FDS"), "LISTEN_FDS");
crun_context.preserve_fds += crun_context.listen_fds;
}

Expand Down

0 comments on commit 42d408e

Please sign in to comment.