From b15a1ae5e84e4cbe3602f363a2ce20b24438848e Mon Sep 17 00:00:00 2001 From: Simon McVittie <smcv@collabora.com> Date: Wed, 13 Jan 2021 11:54:48 +0000 Subject: [PATCH] runtime: Use bwrap->envp to run readlink Previously, pv_capture_output() always inherited pressure-vessel-wrap's own environment, and bwrap->envp was ignored. Thanks to @mawww on Github for spotting this. Fixes: f584a55c "runtime: Don't assume container's env is in the PATH" Signed-off-by: Simon McVittie <smcv@collabora.com> --- pressure-vessel/runtime.c | 5 +++-- pressure-vessel/utils.c | 3 ++- pressure-vessel/utils.h | 1 + tests/pressure-vessel/utils.c | 37 ++++++++++++++++++++++++++++++----- 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/pressure-vessel/runtime.c b/pressure-vessel/runtime.c index cb22c91bb..7737e6e4e 100644 --- a/pressure-vessel/runtime.c +++ b/pressure-vessel/runtime.c @@ -318,7 +318,7 @@ runtime_architecture_init (RuntimeArchitecture *self, * assume that this is the same as whether we can run them * on the host, if different. */ argv[0] = self->capsule_capture_libs; - self->ld_so = pv_capture_output (argv, NULL); + self->ld_so = pv_capture_output (argv, NULL, NULL); if (self->ld_so == NULL) { @@ -2843,7 +2843,8 @@ pv_runtime_get_ld_so (PvRuntime *self, flatpak_bwrap_finish (temp_bwrap); *ld_so_in_runtime = pv_capture_output ( - (const char * const *) temp_bwrap->argv->pdata, NULL); + (const char * const *) temp_bwrap->argv->pdata, + (const char * const *) temp_bwrap->envp, NULL); } return TRUE; diff --git a/pressure-vessel/utils.c b/pressure-vessel/utils.c index ba28e4c13..5cb4950d6 100644 --- a/pressure-vessel/utils.c +++ b/pressure-vessel/utils.c @@ -170,6 +170,7 @@ pv_search_path_append (GString *search_path, gchar * pv_capture_output (const char * const * argv, + const char * const * envp, GError **error) { gsize len; @@ -199,7 +200,7 @@ pv_capture_output (const char * const * argv, * that are not close-on-execute will get leaked into the child. */ if (!g_spawn_sync (NULL, /* cwd */ (char **) argv, - NULL, /* env */ + (char **) envp, (G_SPAWN_SEARCH_PATH | G_SPAWN_LEAVE_DESCRIPTORS_OPEN), NULL, NULL, diff --git a/pressure-vessel/utils.h b/pressure-vessel/utils.h index d15b52af3..5d647afa0 100644 --- a/pressure-vessel/utils.h +++ b/pressure-vessel/utils.h @@ -49,6 +49,7 @@ void pv_search_path_append (GString *search_path, const gchar *item); gchar *pv_capture_output (const char * const * argv, + const char * const * envp, GError **error); gpointer pv_hash_table_get_arbitrary_key (GHashTable *table); diff --git a/tests/pressure-vessel/utils.c b/tests/pressure-vessel/utils.c index 3376ff503..5508fb04f 100644 --- a/tests/pressure-vessel/utils.c +++ b/tests/pressure-vessel/utils.c @@ -87,24 +87,25 @@ test_capture_output (Fixture *f, { const gchar * argv[] = { - "printf", "hello\\n", NULL + "printf", "hello\\n", NULL, NULL, }; g_autofree gchar *output = NULL; g_autoptr(GError) error = NULL; + g_auto(GStrv) envp = g_get_environ (); - output = pv_capture_output (argv, &error); + output = pv_capture_output (argv, NULL, &error); g_assert_cmpstr (output, ==, "hello"); g_assert_no_error (error); g_clear_pointer (&output, g_free); argv[1] = "hello\\nworld"; /* deliberately no trailing newline */ - output = pv_capture_output (argv, &error); + output = pv_capture_output (argv, NULL, &error); g_assert_no_error (error); g_assert_cmpstr (output, ==, "hello\nworld"); g_clear_pointer (&output, g_free); argv[0] = "/nonexistent/doesnotexist"; - output = pv_capture_output (argv, &error); + output = pv_capture_output (argv, NULL, &error); g_assert_nonnull (error); if (error->domain == G_SPAWN_ERROR @@ -129,10 +130,36 @@ test_capture_output (Fixture *f, argv[0] = "false"; argv[1] = NULL; - output = pv_capture_output (argv, &error); + output = pv_capture_output (argv, NULL, &error); g_assert_error (error, G_SPAWN_EXIT_ERROR, 1); g_assert_cmpstr (output, ==, NULL); g_clear_error (&error); + + argv[0] = "sh"; + argv[1] = "-euc"; + argv[2] = "echo \"$PATH\""; + output = pv_capture_output (argv, NULL, &error); + g_assert_no_error (error); + g_assert_cmpstr (output, ==, g_getenv ("PATH")); + g_clear_pointer (&output, g_free); + + envp = g_environ_setenv (envp, "FOO", "bar", TRUE); + argv[0] = "sh"; + argv[1] = "-euc"; + argv[2] = "echo \"${FOO-unset}\""; + output = pv_capture_output (argv, (const char * const *) envp, &error); + g_assert_no_error (error); + g_assert_cmpstr (output, ==, "bar"); + g_clear_pointer (&output, g_free); + + envp = g_environ_unsetenv (envp, "FOO"); + argv[0] = "sh"; + argv[1] = "-euc"; + argv[2] = "echo \"${FOO-unset}\""; + output = pv_capture_output (argv, (const char * const *) envp, &error); + g_assert_no_error (error); + g_assert_cmpstr (output, ==, "unset"); + g_clear_pointer (&output, g_free); } static void -- GitLab