From e64e501b5e40976c3e81d7228e540faa81e5d5f5 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 28 Aug 2023 17:16:36 -0400 Subject: [PATCH] search: Fix a NULL ptr deref with zero terms Here `clang-analyzer` found a legitimate bug, through a quite deep call stack. Before this change, providing zero search terms like this results in a segfault: ``` $ rpmostree_busctl_call_os Search as 0 ``` In exactly the way predicted by the static analysis. Verify we have at least one term at entry into the function, and also add further assertions later. --- src/daemon/rpmostreed-os.cxx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/daemon/rpmostreed-os.cxx b/src/daemon/rpmostreed-os.cxx index 56e3c8d4b2..89307f7795 100644 --- a/src/daemon/rpmostreed-os.cxx +++ b/src/daemon/rpmostreed-os.cxx @@ -1193,11 +1193,16 @@ search_packages_by_filter (HyQuery query, GVariantBuilder *builder, const gchar hy_autoquery HyQuery intermediate_query = hy_query_clone (query); hy_autoquery HyQuery final_query = hy_query_clone (query); + // Must have at least one term + const char *first_term = names[0]; + g_assert (first_term); + int names_count = 0; for (guint i = 0; names[i] != NULL; i++) { names_count++; } + g_assert_cmpint (names_count, >, 0); /* Name/Summary matches */ if (keynames.size () < 2) @@ -1273,11 +1278,11 @@ search_packages_by_filter (HyQuery query, GVariantBuilder *builder, const gchar for (guint i = 0; i < keynames.size (); i++) { hy_query_clear (query); - apply_search_filter (&query, keynames[i], names[0], HY_EQ); + apply_search_filter (&query, keynames[i], first_term, HY_EQ); intermediate_query = hy_query_clone (query); hy_query_clear (query); - apply_search_filter (&query, keynames[i], names[0], HY_SUBSTR); + apply_search_filter (&query, keynames[i], first_term, HY_SUBSTR); hy_query_union (intermediate_query, query); if (i != 0) @@ -1303,6 +1308,13 @@ os_handle_search (RPMOSTreeOS *interface, GDBusMethodInvocation *invocation, sd_journal_print (LOG_INFO, "Handling Search for caller %s", g_dbus_method_invocation_get_sender (invocation)); + if (!names || !*names) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, + "Must specify a term for search"); + return TRUE; + } + g_autoptr (DnfContext) dnfctx = os_create_dnf_context_simple (interface, TRUE, cancellable, &local_error); if (dnfctx == NULL)