Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions src/libcrun/seccomp_notify.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,17 @@ libcrun_load_seccomp_notify_plugins (struct seccomp_notify_context_s **out, cons
ctx->sreq = xmalloc (ctx->sizes.seccomp_notif);
ctx->sresp = xmalloc (ctx->sizes.seccomp_notif_resp);

if (is_empty_string (plugins))
return 0;

b = xstrdup (plugins);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

If plugins is NULL, xstrdup returns NULL, making b NULL. The loop at line 101 will then dereference this NULL pointer, causing a crash. You can prevent this by ensuring b is never NULL, for example by assigning it an empty string if xstrdup returns NULL. This would also make the behavior for NULL plugins consistent with an empty plugin string.

  b = xstrdup (plugins);
  if (!b)
    b = "";


ctx->n_plugins = 1;
for (it = b; it; it = strchr (it, ':'))
ctx->n_plugins++;
for (it = b; *it; it++)
if (*it == ':')
ctx->n_plugins++;

ctx->plugins = xmalloc0 (sizeof (struct plugin) * (ctx->n_plugins + 1));

b = xstrdup (plugins);
for (s = 0, it = strtok_r (b, ":", &saveptr); it; s++, it = strtok_r (NULL, ":", &saveptr))
{
run_oci_seccomp_notify_plugin_version_cb version_cb;
Expand Down Expand Up @@ -254,6 +258,7 @@ libcrun_free_seccomp_notify_plugins (struct seccomp_notify_context_s *ctx, libcr
dlclose (ctx->plugins[i].handle);
}

free (ctx->plugins);
free (ctx);

return 0;
Expand Down
24 changes: 23 additions & 1 deletion tests/tests_libcrun_seccomp_notify.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,27 @@ test_load_nonexistent_plugin ()
return 0;
}

/* Test load with multiple non-existent plugins to verify cleanup of n_plugins. */
static int
test_load_multiple_nonexistent_plugins ()
{
libcrun_error_t err = NULL;
struct seccomp_notify_context_s *ctx = NULL;
int ret;

ret = libcrun_load_seccomp_notify_plugins (&ctx, "/nonexistent/p1.so:/nonexistent/p2.so:/nonexistent/p3.so", NULL, &err);
if (ret >= 0)
{
if (ctx)
libcrun_free_seccomp_notify_plugins (ctx, &err);
crun_error_release (&err);
return -1;
}

crun_error_release (&err);
return 0;
}

/* Test seccomp_notify_plugins returns error without seccomp support */
static int
test_notify_no_seccomp ()
Expand Down Expand Up @@ -167,11 +188,12 @@ int
main ()
{
int id = 1;
printf ("1..5\n");
printf ("1..6\n");
RUN_TEST (test_cleanup_null);
RUN_TEST (test_free_null_context);
RUN_TEST (test_load_invalid_path);
RUN_TEST (test_load_nonexistent_plugin);
RUN_TEST (test_load_multiple_nonexistent_plugins);
RUN_TEST (test_notify_no_seccomp);
return 0;
}