diff --git a/pressure-vessel/adverb.1.md b/pressure-vessel/adverb.1.md index c932d9f52ac417ea02fd78a733320b852cbfc2ab..85fe81fb806b471217c349dcff3aae509106d8f3 100644 --- a/pressure-vessel/adverb.1.md +++ b/pressure-vessel/adverb.1.md @@ -29,7 +29,6 @@ pressure-vessel-adverb - wrap processes in various ways [**--[no-]wait**] [**--[no-]write**] **--lock-file** *FILENAME*...] - [**--verbose**] [**--**] *COMMAND* [*ARGUMENTS...*] diff --git a/pressure-vessel/adverb.c b/pressure-vessel/adverb.c index b8b6325ac5ec3453ddd855ca07d5f50569c31cac..10adefb2cc285b6ed480d3c942550178bffe29ff 100644 --- a/pressure-vessel/adverb.c +++ b/pressure-vessel/adverb.c @@ -92,8 +92,8 @@ typedef struct static PreloadModule opt_preload_modules[] = { - { "LD_AUDIT", NULL, NULL }, - { "LD_PRELOAD", NULL, NULL }, + { "LD_AUDIT", NULL }, + { "LD_PRELOAD", NULL }, }; static void @@ -223,7 +223,7 @@ opt_ld_audit_cb (const gchar *option_name, GError **error) { pv_append_preload_module (opt_preload_modules, G_N_ELEMENTS (opt_preload_modules), - "LD_AUDIT", value, FALSE); + "LD_AUDIT", value); return TRUE; } @@ -234,7 +234,7 @@ opt_ld_preload_cb (const gchar *option_name, GError **error) { pv_append_preload_module (opt_preload_modules, G_N_ELEMENTS (opt_preload_modules), - "LD_PRELOAD", value, FALSE); + "LD_PRELOAD", value); return TRUE; } @@ -470,7 +470,7 @@ generate_lib_temp_dirs (LibTempDirs *lib_temp_dirs, GError **error) { g_autoptr(SrtSystemInfo) info = NULL; - gsize i; + gsize abi; g_return_val_if_fail (lib_temp_dirs != NULL, FALSE); g_return_val_if_fail (lib_temp_dirs->abi_paths == NULL, FALSE); @@ -487,12 +487,12 @@ generate_lib_temp_dirs (LibTempDirs *lib_temp_dirs, lib_temp_dirs->abi_paths = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - for (i = 0; i < G_N_ELEMENTS (abi_tuples_details); i++) + for (abi = 0; abi < G_N_ELEMENTS (abi_tuples_details); abi++) { g_autofree gchar *libdl_platform = NULL; g_autofree gchar *abi_path = NULL; libdl_platform = srt_system_info_dup_libdl_platform (info, - abi_tuples_details[i].abi, + abi_tuples_details[abi].abi, error); if (!libdl_platform) return glnx_prefix_error (error, @@ -504,7 +504,7 @@ generate_lib_temp_dirs (LibTempDirs *lib_temp_dirs, return glnx_throw_errno_prefix (error, "Unable to create \"%s\"", abi_path); g_hash_table_insert (lib_temp_dirs->abi_paths, - g_strdup (abi_tuples_details[i].abi), + g_strdup (abi_tuples_details[abi].abi), g_steal_pointer (&abi_path)); } @@ -946,7 +946,7 @@ main (int argc, for (i = 0; i < G_N_ELEMENTS (opt_preload_modules); i++) { const char *variable = opt_preload_modules[i].variable; - const GPtrArray *values = opt_preload_modules[i].original_values; + const GPtrArray *values = opt_preload_modules[i].values; g_autofree gchar *platform_overlay_path = NULL; g_autoptr(GPtrArray) search_path = NULL; g_autoptr(GString) buffer = NULL; @@ -994,14 +994,14 @@ main (int argc, { g_autofree gchar *link = NULL; - for (gsize jj = 0; jj < G_N_ELEMENTS (abi_tuples_details); jj++) + for (gsize abi = 0; abi < G_N_ELEMENTS (abi_tuples_details); abi++) { g_autofree gchar *expected_suffix = g_strdup_printf ("/%s/gameoverlayrenderer.so", - abi_tuples_details[jj].directory_name); + abi_tuples_details[abi].directory_name); if (g_str_has_suffix (preload, expected_suffix)) { link = g_build_filename (g_hash_table_lookup (lib_temp_dirs->abi_paths, - abi_tuples_details[jj].abi), + abi_tuples_details[abi].abi), "gameoverlayrenderer.so", NULL); break; } diff --git a/pressure-vessel/flatpak-exports-private.h b/pressure-vessel/flatpak-exports-private.h index 2bb2f29b14f240ee5ff3c17f706cb3bd1d33d6cb..ccf405bbfb5ada0cd63ce17965400998ad1f6639 100644 --- a/pressure-vessel/flatpak-exports-private.h +++ b/pressure-vessel/flatpak-exports-private.h @@ -1,5 +1,5 @@ /* - * Taken from Flatpak, last updated: 1.11.2 + * Taken from Flatpak, last updated: 1.11.2-15-gc392e5ad * Copyright © 2014-2018 Red Hat, Inc * SPDX-License-Identifier: LGPL-2.1-or-later * @@ -65,8 +65,21 @@ FlatpakFilesystemMode flatpak_exports_path_get_mode (FlatpakExports *exports, G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakExports, flatpak_exports_free); +/* + * FlatpakExportsTestFlags: + * @FLATPAK_EXPORTS_TEST_FLAGS_AUTOFS: Pretend everything is an autofs. + * + * Flags used to provide mock behaviour during unit testing. + */ +typedef enum +{ + FLATPAK_EXPORTS_TEST_FLAGS_AUTOFS = (1 << 0), + FLATPAK_EXPORTS_TEST_FLAGS_NONE = 0 +} FlatpakExportsTestFlags; + void flatpak_exports_take_host_fd (FlatpakExports *exports, int fd); - +void flatpak_exports_set_test_flags (FlatpakExports *exports, + FlatpakExportsTestFlags flags); #endif /* __FLATPAK_EXPORTS_H__ */ diff --git a/pressure-vessel/flatpak-exports.c b/pressure-vessel/flatpak-exports.c index 5b224b57b49ba41b28a87aaea397c51b7c3f31d3..9bd653057359b5f8a3ddcb24087c17e5510afccc 100644 --- a/pressure-vessel/flatpak-exports.c +++ b/pressure-vessel/flatpak-exports.c @@ -1,5 +1,5 @@ /* - * Taken from Flatpak, last updated: 1.11.2 + * Taken from Flatpak, last updated: 1.11.2-15-gc392e5ad * Copyright © 2014-2019 Red Hat, Inc * SPDX-License-Identifier: LGPL-2.1-or-later * @@ -111,6 +111,7 @@ struct _FlatpakExports FlatpakFilesystemMode host_etc; FlatpakFilesystemMode host_os; int host_fd; + FlatpakExportsTestFlags test_flags; }; /* @@ -127,6 +128,13 @@ flatpak_exports_take_host_fd (FlatpakExports *exports, exports->host_fd = fd; } +void +flatpak_exports_set_test_flags (FlatpakExports *exports, + FlatpakExportsTestFlags flags) +{ + exports->test_flags = flags; +} + static gboolean flatpak_exports_stat_in_host (FlatpakExports *exports, const char *abs_path, @@ -140,7 +148,11 @@ flatpak_exports_stat_in_host (FlatpakExports *exports, { /* If abs_path is "/usr", then stat "usr" relative to host_fd. * As a special case, if abs_path is "/", stat host_fd itself, - * due to the use of AT_EMPTY_PATH. */ + * due to the use of AT_EMPTY_PATH. + * + * This won't work if ${host_fd}/${abs_path} contains symlinks + * that are absolute or otherwise escape from the mock root, + * so be careful not to do that in unit tests. */ return glnx_fstatat (exports->host_fd, &abs_path[1], buf, AT_EMPTY_PATH | flags, error); @@ -156,6 +168,8 @@ flatpak_exports_readlink_in_host (FlatpakExports *exports, { g_return_val_if_fail (abs_path[0] == '/', FALSE); + /* Similar to flatpak_exports_stat_in_host, this assumes the mock root + * doesn't contain symlinks that escape from the mock root. */ if (exports->host_fd >= 0) return glnx_readlinkat_malloc (exports->host_fd, &abs_path[1], NULL, error); @@ -163,6 +177,61 @@ flatpak_exports_readlink_in_host (FlatpakExports *exports, return glnx_readlinkat_malloc (AT_FDCWD, abs_path, NULL, error); } +/* path must be absolute, but this is not checked because assertions + * are not async-signal-safe. */ +static int +flatpak_exports_open_in_host_async_signal_safe (FlatpakExports *exports, + const char *abs_path, + int flags) +{ + flags |= O_CLOEXEC; + + if (exports->host_fd >= 0) + { + /* Similar to flatpak_exports_stat_in_host, this assumes the mock root + * doesn't contain symlinks that escape from the mock root. */ + return openat (exports->host_fd, &abs_path[1], + flags); + } + + return openat (AT_FDCWD, abs_path, flags); +} + +static int +flatpak_exports_open_in_host (FlatpakExports *exports, + const char *abs_path, + int flags) +{ + g_return_val_if_fail (abs_path[0] == '/', -1); + return flatpak_exports_open_in_host_async_signal_safe (exports, abs_path, flags); +} + +static char * +flatpak_exports_resolve_link_in_host (FlatpakExports *exports, + const char *abs_path, + GError **error) +{ + g_return_val_if_fail (abs_path[0] == '/', FALSE); + + if (exports->host_fd >= 0) + { + g_autofree char *fd_path = g_strdup_printf ("/proc/self/fd/%d/", + exports->host_fd); + g_autofree char *real_path = g_strdup_printf ("%s%s", fd_path, &abs_path[1]); + g_autofree char *resolved = flatpak_resolve_link (real_path, error); + + if (resolved == NULL) + return NULL; + + if (!g_str_has_prefix (resolved, fd_path)) + return glnx_null_throw (error, "Symbolic link escapes from mock root"); + + return g_strdup (resolved + strlen (fd_path) - 1); + } + + return flatpak_resolve_link (abs_path, error); +} + static void exported_path_free (ExportedPath *exported_path) { @@ -183,6 +252,7 @@ flatpak_exports_new (void) void flatpak_exports_free (FlatpakExports *exports) { + glnx_close_fd (&exports->host_fd); g_hash_table_destroy (exports->hash); g_free (exports); } @@ -271,22 +341,24 @@ compare_eps (const ExportedPath *a, /* This differs from g_file_test (path, G_FILE_TEST_IS_DIR) which returns true if the path is a symlink to a dir */ static gboolean -path_is_dir (const char *path) +path_is_dir (FlatpakExports *exports, + const char *path) { struct stat s; - if (lstat (path, &s) != 0) + if (!flatpak_exports_stat_in_host (exports, path, &s, AT_SYMLINK_NOFOLLOW, NULL)) return FALSE; return S_ISDIR (s.st_mode); } static gboolean -path_is_symlink (const char *path) +path_is_symlink (FlatpakExports *exports, + const char *path) { struct stat s; - if (lstat (path, &s) != 0) + if (!flatpak_exports_stat_in_host (exports, path, &s, AT_SYMLINK_NOFOLLOW, NULL)) return FALSE; return S_ISLNK (s.st_mode); @@ -339,7 +411,9 @@ flatpak_exports_append_bwrap_args (FlatpakExports *exports, { if (!path_parent_is_mapped (keys, n_keys, exports->hash, path)) { - g_autofree char *resolved = flatpak_resolve_link (path, NULL); + g_autofree char *resolved = flatpak_exports_resolve_link_in_host (exports, + path, + NULL); if (resolved) { g_autofree char *parent = g_path_get_dirname (path); @@ -352,7 +426,7 @@ flatpak_exports_append_bwrap_args (FlatpakExports *exports, { /* Mount a tmpfs to hide the subdirectory, but only if there is a pre-existing dir we can mount the path on. */ - if (path_is_dir (path)) + if (path_is_dir (exports, path)) { if (!path_parent_is_mapped (keys, n_keys, exports->hash, path)) /* If the parent is not mapped, it will be a tmpfs, no need to mount another one */ @@ -363,7 +437,7 @@ flatpak_exports_append_bwrap_args (FlatpakExports *exports, } else if (ep->mode == FAKE_MODE_DIR) { - if (path_is_dir (path)) + if (path_is_dir (exports, path)) flatpak_bwrap_add_args (bwrap, "--dir", path, NULL); } else @@ -509,6 +583,7 @@ flatpak_exports_path_get_mode (FlatpakExports *exports, g_qsort_with_data (keys, n_keys, sizeof (char *), (GCompareDataFunc) flatpak_strcmp0_ptr, NULL); + /* Syntactic canonicalization only, no need to use host_fd */ path = canonical = flatpak_canonicalize_filename (path); parts = g_strsplit (path + 1, "/", -1); @@ -526,9 +601,13 @@ flatpak_exports_path_get_mode (FlatpakExports *exports, if (path_is_mapped (keys, n_keys, exports->hash, path_builder->str, &is_readonly)) { - if (lstat (path_builder->str, &st) != 0) + g_autoptr(GError) stat_error = NULL; + + if (!flatpak_exports_stat_in_host (exports, path_builder->str, &st, AT_SYMLINK_NOFOLLOW, &stat_error)) { - if (errno == ENOENT && parts[i + 1] == NULL && !is_readonly) + if (g_error_matches (stat_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) && + parts[i + 1] == NULL && + !is_readonly) { /* Last element was mapped but isn't there, this is * OK (used for the save case) if we the parent is @@ -543,7 +622,9 @@ flatpak_exports_path_get_mode (FlatpakExports *exports, if (S_ISLNK (st.st_mode)) { - g_autofree char *resolved = flatpak_resolve_link (path_builder->str, NULL); + g_autofree char *resolved = flatpak_exports_resolve_link_in_host (exports, + path_builder->str, + NULL); g_autoptr(GString) path2_builder = NULL; int j; @@ -618,7 +699,8 @@ do_export_path (FlatpakExports *exports, * have to mess with forks and stuff to be able to handle the timeout. */ static gboolean -check_if_autofs_works (const char *path) +check_if_autofs_works (FlatpakExports *exports, + const char *path) { int selfpipe[2]; struct timeval timeout; @@ -627,6 +709,8 @@ check_if_autofs_works (const char *path) int res; int wstatus; + g_return_val_if_fail (path[0] == '/', FALSE); + if (pipe2 (selfpipe, O_CLOEXEC) == -1) return FALSE; @@ -646,7 +730,10 @@ check_if_autofs_works (const char *path) /* Note: open, close and _exit are signal-async-safe, so it is ok to call in the child after fork */ close (selfpipe[0]); /* Close unused read end */ - int dir_fd = open (path, O_RDONLY | O_NONBLOCK | O_CLOEXEC | O_DIRECTORY); + + int dir_fd = flatpak_exports_open_in_host_async_signal_safe (exports, + path, + O_RDONLY | O_NONBLOCK | O_DIRECTORY); _exit (dir_fd == -1 ? 1 : 0); } @@ -678,6 +765,12 @@ check_if_autofs_works (const char *path) if (!WIFEXITED (wstatus) || WEXITSTATUS (wstatus) != 0) return FALSE; + if (G_UNLIKELY (exports->test_flags & FLATPAK_EXPORTS_TEST_FLAGS_AUTOFS)) + { + if (strcmp (path, "/broken-autofs") == 0) + return FALSE; + } + return TRUE; } @@ -710,7 +803,7 @@ _exports_path_expose (FlatpakExports *exports, } /* Check if it exists at all */ - o_path_fd = open (path, O_PATH | O_NOFOLLOW | O_CLOEXEC); + o_path_fd = flatpak_exports_open_in_host (exports, path, O_PATH | O_NOFOLLOW); if (o_path_fd == -1) return FALSE; @@ -728,15 +821,18 @@ _exports_path_expose (FlatpakExports *exports, if (fstatfs (o_path_fd, &stfs) != 0) return FALSE; - if (stfs.f_type == AUTOFS_SUPER_MAGIC) + if (stfs.f_type == AUTOFS_SUPER_MAGIC || + (G_UNLIKELY (exports->test_flags & FLATPAK_EXPORTS_TEST_FLAGS_AUTOFS) && + S_ISDIR (st.st_mode))) { - if (!check_if_autofs_works (path)) + if (!check_if_autofs_works (exports, path)) { g_debug ("ignoring blocking autofs path %s", path); return FALSE; } } + /* Syntactic canonicalization only, no need to use host_fd */ path = canonical = flatpak_canonicalize_filename (path); for (i = 0; dont_export_in[i] != NULL; i++) @@ -770,9 +866,9 @@ _exports_path_expose (FlatpakExports *exports, if (slash) *slash = 0; - if (path_is_symlink (path) && !never_export_as_symlink (path)) + if (path_is_symlink (exports, path) && !never_export_as_symlink (path)) { - g_autofree char *resolved = flatpak_resolve_link (path, NULL); + g_autofree char *resolved = flatpak_exports_resolve_link_in_host (exports, path, NULL); g_autofree char *new_target = NULL; if (resolved) diff --git a/pressure-vessel/utils.c b/pressure-vessel/utils.c index d94c2819d09b9b2c69f125cdffc081350a7bc306..f1a5d4a0ba7051a0784207219222abc2cf645abe 100644 --- a/pressure-vessel/utils.c +++ b/pressure-vessel/utils.c @@ -1001,8 +1001,6 @@ pv_delete_dangling_symlink (int dirfd, * @n_preload_modules: Size of @preload_modules * @variable: Variable where @value will be appended to * @value: Value that needs to be appended - * @adjusted_value: If #TRUE, @value will be appended to the adjusted values - * array, otherwise it will be appended to the original values array * * Append @value to the #PreloadModule whose "variable" is the same as the * provided @variable. @@ -1011,8 +1009,7 @@ void pv_append_preload_module (PreloadModule preload_modules[], gsize n_preload_modules, const char *variable, - const char *value, - gboolean adjusted_value) + const char *value) { gsize i; @@ -1029,20 +1026,10 @@ pv_append_preload_module (PreloadModule preload_modules[], if (i == n_preload_modules) g_return_if_reached (); - if (adjusted_value) - { - if (preload_modules[i].adjusted_values == NULL) - preload_modules[i].adjusted_values = g_ptr_array_new_with_free_func (g_free); - - g_ptr_array_add (preload_modules[i].adjusted_values, g_strdup (value)); - } - else - { - if (preload_modules[i].original_values == NULL) - preload_modules[i].original_values = g_ptr_array_new_with_free_func (g_free); + if (preload_modules[i].values == NULL) + preload_modules[i].values = g_ptr_array_new_with_free_func (g_free); - g_ptr_array_add (preload_modules[i].original_values, g_strdup (value)); - } + g_ptr_array_add (preload_modules[i].values, g_strdup (value)); } /** @@ -1059,8 +1046,5 @@ pv_preload_modules_free (PreloadModule preload_modules[], gsize i; for (i = 0; i < n_preload_modules; i++) - { - g_clear_pointer (&preload_modules[i].original_values, g_ptr_array_unref); - g_clear_pointer (&preload_modules[i].adjusted_values, g_ptr_array_unref); - } + g_clear_pointer (&preload_modules[i].values, g_ptr_array_unref); } diff --git a/pressure-vessel/utils.h b/pressure-vessel/utils.h index 3693956d7a6a25c7268ace49c5f72326adf6b9d1..fb92733a0f7e1682862840c07588120f46db1368 100644 --- a/pressure-vessel/utils.h +++ b/pressure-vessel/utils.h @@ -47,8 +47,7 @@ typedef struct { const char *variable; - GPtrArray *original_values; - GPtrArray *adjusted_values; + GPtrArray *values; } PreloadModule; void pv_get_current_dirs (gchar **cwd_p, @@ -92,8 +91,7 @@ void pv_delete_dangling_symlink (int dirfd, void pv_append_preload_module (PreloadModule preload_modules[], gsize n_preload_modules, const char *variable, - const char *value, - gboolean adjusted_value); + const char *value); void pv_preload_modules_free (PreloadModule preload_modules[], diff --git a/pressure-vessel/wrap.c b/pressure-vessel/wrap.c index fba79d5782e65780647ab2d2d152ae78827b40c0..87e0cd0d36996411607e42798b28bc210dfa7a9d 100644 --- a/pressure-vessel/wrap.c +++ b/pressure-vessel/wrap.c @@ -716,8 +716,14 @@ static char *opt_write_final_argv = NULL; static PreloadModule opt_preload_modules[] = { - { "LD_AUDIT", NULL, NULL }, - { "LD_PRELOAD", NULL, NULL }, + { "LD_AUDIT", NULL }, + { "LD_PRELOAD", NULL }, +}; +static const char * const adverb_preload_options[G_N_ELEMENTS (opt_preload_modules)] = +{ + /* Must be in the same order as opt_preload_modules */ + "--ld-audit", + "--ld-preload", }; /* @@ -741,7 +747,7 @@ opt_host_ld_preload_cb (const gchar *option_name, g_warning ("%s is deprecated, use --ld-preload=%s instead", option_name, value); pv_append_preload_module (opt_preload_modules, G_N_ELEMENTS (opt_preload_modules), - "LD_PRELOAD", value, FALSE); + "LD_PRELOAD", value); return TRUE; } @@ -752,7 +758,7 @@ opt_ld_audit_cb (const gchar *option_name, GError **error) { pv_append_preload_module (opt_preload_modules, G_N_ELEMENTS (opt_preload_modules), - "LD_AUDIT", value, FALSE); + "LD_AUDIT", value); return TRUE; } @@ -763,7 +769,7 @@ opt_ld_preload_cb (const gchar *option_name, GError **error) { pv_append_preload_module (opt_preload_modules, G_N_ELEMENTS (opt_preload_modules), - "LD_PRELOAD", value, FALSE); + "LD_PRELOAD", value); return TRUE; } @@ -1324,6 +1330,7 @@ main (int argc, g_autoptr(FILE) original_stdout = NULL; g_autoptr(GArray) pass_fds_through_adverb = g_array_new (FALSE, FALSE, sizeof (int)); const char *steam_app_id; + g_autoptr(GPtrArray) adverb_preload_argv = NULL; setlocale (LC_ALL, ""); @@ -2084,6 +2091,25 @@ main (int argc, FLATPAK_FILESYSTEM_MODE_READ_WRITE, "/tmp"); + if (flatpak_subsandbox != NULL) + { + /* We special case libshared-library-guard because usually + * its blockedlist file is located in `/app` and we need + * to change that to the `/run/parent` counterpart */ + const gchar *blockedlist = "/app/etc/freedesktop-sdk.ld.so.blockedlist"; + + if (g_file_test (blockedlist, G_FILE_TEST_EXISTS)) + { + g_autofree gchar *adjusted_blockedlist = NULL; + adjusted_blockedlist = g_build_filename ("/run/parent", + blockedlist, NULL); + pv_environ_setenv (container_env, "SHARED_LIBRARY_GUARD_CONFIG", + adjusted_blockedlist); + } + } + + adverb_preload_argv = g_ptr_array_new_with_free_func (g_free); + /* We need the LD_PRELOADs from Steam visible at the paths that were * used for them, which might be their physical rather than logical * locations. Steam doesn't generally use LD_AUDIT, but the Steam app @@ -2091,7 +2117,8 @@ main (int argc, for (i = 0; i < G_N_ELEMENTS (opt_preload_modules); i++) { const char *variable = opt_preload_modules[i].variable; - const GPtrArray *values = opt_preload_modules[i].original_values; + const GPtrArray *values = opt_preload_modules[i].values; + const char *option = adverb_preload_options[i]; gsize len; gsize j; @@ -2139,32 +2166,18 @@ main (int argc, adjusted_path = g_build_filename ("/run/parent", preload, NULL); g_debug ("%s -> %s", preload, adjusted_path); - pv_append_preload_module (opt_preload_modules, - G_N_ELEMENTS (opt_preload_modules), - variable, adjusted_path, TRUE); - - if (g_str_has_suffix (preload, "/libshared-library-guard.so")) - { - /* We special case libshared-library-guard because usually - * its blockedlist file is located in `/app` and we need - * to change that to the `/run/parent` counterpart */ - const gchar *blockedlist = "/app/etc/freedesktop-sdk.ld.so.blockedlist"; - if (g_file_test (blockedlist, G_FILE_TEST_EXISTS)) - { - g_autofree gchar *adjusted_blockedlist = NULL; - adjusted_blockedlist = g_build_filename ("/run/parent", - blockedlist, NULL); - pv_environ_setenv (container_env, "SHARED_LIBRARY_GUARD_CONFIG", - adjusted_blockedlist); - } - } + g_ptr_array_add (adverb_preload_argv, + g_strdup_printf ("%s=%s", + option, + adjusted_path)); } else { g_debug ("%s -> unmodified", preload); - pv_append_preload_module (opt_preload_modules, - G_N_ELEMENTS (opt_preload_modules), - variable, preload, TRUE); + g_ptr_array_add (adverb_preload_argv, + g_strdup_printf ("%s=%s", + option, + preload)); } /* No FlatpakExports here: any file not in /usr or /app that @@ -2186,9 +2199,10 @@ main (int argc, /* When using a runtime we can't write to /usr/ or /libQUAL/, * so redirect this preloaded module to the corresponding * location in /run/host. */ - pv_append_preload_module (opt_preload_modules, - G_N_ELEMENTS (opt_preload_modules), - variable, adjusted_path, TRUE); + g_ptr_array_add (adverb_preload_argv, + g_strdup_printf ("%s=%s", + option, + adjusted_path)); } else { @@ -2209,9 +2223,10 @@ main (int argc, preload); } - pv_append_preload_module (opt_preload_modules, - G_N_ELEMENTS (opt_preload_modules), - variable, preload, TRUE); + g_ptr_array_add (adverb_preload_argv, + g_strdup_printf ("%s=%s", + option, + preload)); } } else @@ -2621,36 +2636,7 @@ main (int argc, break; } - for (i = 0; i < G_N_ELEMENTS (opt_preload_modules); i++) - { - const gchar *variable = opt_preload_modules[i].variable; - const GPtrArray *values = opt_preload_modules[i].adjusted_values; - const gchar *option = NULL; - gsize j; - - if (g_strcmp0 (variable, "LD_AUDIT") == 0) - { - option = "--ld-audit"; - } - else if (g_strcmp0 (variable, "LD_PRELOAD") == 0) - { - option = "--ld-preload"; - } - else - { - /* Programming error: this logic needs to be updated - * to handle this new preload module */ - g_critical ("Unhandled preload module %s", variable); - continue; - } - - if (values == NULL) - continue; - - for (j = 0; j < values->len; j++) - flatpak_bwrap_add_arg_printf (adverb_argv, "%s=%s", option, - (gchar *)g_ptr_array_index (values, j)); - } + flatpak_bwrap_append_args (adverb_argv, adverb_preload_argv); if (opt_verbose) flatpak_bwrap_add_arg (adverb_argv, "--verbose"); @@ -2793,6 +2779,7 @@ out: pv_preload_modules_free (opt_preload_modules, G_N_ELEMENTS (opt_preload_modules)); + g_clear_pointer (&adverb_preload_argv, g_ptr_array_unref); g_clear_pointer (&opt_env_if_host, g_strfreev); g_clear_pointer (&opt_freedesktop_app_id, g_free); g_clear_pointer (&opt_steam_app_id, g_free);