exports: Move error handling up into caller

This lets flatpak_context_export() or other callers decide how they want
to handle failure to export each path. For now, the callers in
FlatpakExports are still using g_debug() unconditionally, but we can now
have somewhat better test coverage.

Helps: https://github.com/flatpak/flatpak/issues/1357
Helps: https://github.com/flatpak/flatpak/issues/5035
Helps: https://github.com/flatpak/flatpak/issues/5205
Helps: https://github.com/flatpak/flatpak/issues/5207
Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
Simon McVittie
2022-12-12 15:25:51 +00:00
parent 1b49de1890
commit 3f0a2de2a2
4 changed files with 306 additions and 164 deletions

View File

@@ -2457,6 +2457,27 @@ const char *dont_mount_in_root[] = {
NULL
};
static void
log_cannot_export_error (FlatpakFilesystemMode mode,
const char *path,
const GError *error)
{
switch (mode)
{
case FLATPAK_FILESYSTEM_MODE_NONE:
g_debug ("Not replacing \"%s\" with tmpfs: %s",
path, error->message);
break;
case FLATPAK_FILESYSTEM_MODE_CREATE:
case FLATPAK_FILESYSTEM_MODE_READ_ONLY:
case FLATPAK_FILESYSTEM_MODE_READ_WRITE:
g_debug ("Not sharing \"%s\" with sandbox: %s",
path, error->message);
break;
}
}
static void
flatpak_context_export (FlatpakContext *context,
FlatpakExports *exports,
@@ -2471,6 +2492,7 @@ flatpak_context_export (FlatpakContext *context,
FlatpakFilesystemMode fs_mode, os_mode, etc_mode, home_mode;
GHashTableIter iter;
gpointer key, value;
g_autoptr(GError) local_error = NULL;
if (xdg_dirs_conf_out != NULL)
xdg_dirs_conf = g_string_new ("");
@@ -2496,11 +2518,21 @@ flatpak_context_export (FlatpakContext *context,
continue;
path = g_build_filename ("/", dirent->d_name, NULL);
flatpak_exports_add_path_expose (exports, fs_mode, path);
if (!flatpak_exports_add_path_expose (exports, fs_mode, path, &local_error))
{
log_cannot_export_error (fs_mode, path, local_error);
g_clear_error (&local_error);
}
}
closedir (dir);
}
flatpak_exports_add_path_expose (exports, fs_mode, "/run/media");
if (!flatpak_exports_add_path_expose (exports, fs_mode, "/run/media", &local_error))
{
log_cannot_export_error (fs_mode, "/run/media", local_error);
g_clear_error (&local_error);
}
}
os_mode = MAX (GPOINTER_TO_INT (g_hash_table_lookup (context->filesystems, "host-os")),
@@ -2521,7 +2553,12 @@ flatpak_context_export (FlatpakContext *context,
g_info ("Allowing homedir access");
home_access = TRUE;
flatpak_exports_add_path_expose (exports, MAX (home_mode, fs_mode), g_get_home_dir ());
if (!flatpak_exports_add_path_expose (exports, MAX (home_mode, fs_mode), g_get_home_dir (), &local_error))
{
log_cannot_export_error (MAX (home_mode, fs_mode), g_get_home_dir (),
local_error);
g_clear_error (&local_error);
}
}
g_hash_table_iter_init (&iter, context->filesystems);
@@ -2571,7 +2608,11 @@ flatpak_context_export (FlatpakContext *context,
g_string_append_printf (xdg_dirs_conf, "%s=\"%s\"\n",
config_key, path);
flatpak_exports_add_path_expose_or_hide (exports, mode, subpath);
if (!flatpak_exports_add_path_expose_or_hide (exports, mode, subpath, &local_error))
{
log_cannot_export_error (mode, subpath, local_error);
g_clear_error (&local_error);
}
}
}
else if (g_str_has_prefix (filesystem, "~/"))
@@ -2586,8 +2627,11 @@ flatpak_context_export (FlatpakContext *context,
g_info ("Unable to create directory %s", path);
}
if (g_file_test (path, G_FILE_TEST_EXISTS))
flatpak_exports_add_path_expose_or_hide (exports, mode, path);
if (!flatpak_exports_add_path_expose_or_hide (exports, mode, path, &local_error))
{
log_cannot_export_error (mode, path, local_error);
g_clear_error (&local_error);
}
}
else if (g_str_has_prefix (filesystem, "/"))
{
@@ -2597,8 +2641,11 @@ flatpak_context_export (FlatpakContext *context,
g_info ("Unable to create directory %s", filesystem);
}
if (g_file_test (filesystem, G_FILE_TEST_EXISTS))
flatpak_exports_add_path_expose_or_hide (exports, mode, filesystem);
if (!flatpak_exports_add_path_expose_or_hide (exports, mode, filesystem, &local_error))
{
log_cannot_export_error (mode, filesystem, local_error);
g_clear_error (&local_error);
}
}
else
{
@@ -2611,18 +2658,42 @@ flatpak_context_export (FlatpakContext *context,
g_autoptr(GFile) apps_dir = g_file_get_parent (app_id_dir);
int i;
/* Hide the .var/app dir by default (unless explicitly made visible) */
flatpak_exports_add_path_tmpfs (exports, flatpak_file_get_path_cached (apps_dir));
if (!flatpak_exports_add_path_tmpfs (exports,
flatpak_file_get_path_cached (apps_dir),
&local_error))
{
log_cannot_export_error (FLATPAK_FILESYSTEM_MODE_NONE,
flatpak_file_get_path_cached (apps_dir),
local_error);
g_clear_error (&local_error);
}
/* But let the app write to the per-app dir in it */
flatpak_exports_add_path_expose (exports, FLATPAK_FILESYSTEM_MODE_READ_WRITE,
flatpak_file_get_path_cached (app_id_dir));
if (!flatpak_exports_add_path_expose (exports, FLATPAK_FILESYSTEM_MODE_READ_WRITE,
flatpak_file_get_path_cached (app_id_dir),
&local_error))
{
log_cannot_export_error (FLATPAK_FILESYSTEM_MODE_READ_WRITE,
flatpak_file_get_path_cached (apps_dir),
local_error);
g_clear_error (&local_error);
}
if (extra_app_id_dirs != NULL)
{
for (i = 0; i < extra_app_id_dirs->len; i++)
{
GFile *extra_app_id_dir = g_ptr_array_index (extra_app_id_dirs, i);
flatpak_exports_add_path_expose (exports, FLATPAK_FILESYSTEM_MODE_READ_WRITE,
flatpak_file_get_path_cached (extra_app_id_dir));
if (!flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_WRITE,
flatpak_file_get_path_cached (extra_app_id_dir),
&local_error))
{
log_cannot_export_error (FLATPAK_FILESYSTEM_MODE_READ_WRITE,
flatpak_file_get_path_cached (extra_app_id_dir),
local_error);
g_clear_error (&local_error);
}
}
}
}
@@ -2686,13 +2757,27 @@ flatpak_context_get_exports_full (FlatpakContext *context,
if (include_default_dirs)
{
g_autoptr(GFile) user_flatpak_dir = NULL;
g_autoptr(GError) local_error = NULL;
/* Hide the flatpak dir by default (unless explicitly made visible) */
user_flatpak_dir = flatpak_get_user_base_dir_location ();
flatpak_exports_add_path_tmpfs (exports, flatpak_file_get_path_cached (user_flatpak_dir));
if (!flatpak_exports_add_path_tmpfs (exports,
flatpak_file_get_path_cached (user_flatpak_dir),
&local_error))
{
log_cannot_export_error (FLATPAK_FILESYSTEM_MODE_NONE,
flatpak_file_get_path_cached (user_flatpak_dir),
local_error);
g_clear_error (&local_error);
}
/* Ensure we always have a homedir */
flatpak_exports_add_path_dir (exports, g_get_home_dir ());
if (!flatpak_exports_add_path_dir (exports, g_get_home_dir (), &local_error))
{
g_debug ("Unable to provide a temporary home directory in the sandbox: %s",
local_error->message);
g_clear_error (&local_error);
}
}
return g_steal_pointer (&exports);

View File

@@ -43,16 +43,20 @@ void flatpak_exports_add_host_etc_expose (FlatpakExports *exports,
FlatpakFilesystemMode mode);
void flatpak_exports_add_host_os_expose (FlatpakExports *exports,
FlatpakFilesystemMode mode);
void flatpak_exports_add_path_expose (FlatpakExports *exports,
FlatpakFilesystemMode mode,
const char *path);
void flatpak_exports_add_path_tmpfs (FlatpakExports *exports,
const char *path);
void flatpak_exports_add_path_expose_or_hide (FlatpakExports *exports,
FlatpakFilesystemMode mode,
const char *path);
void flatpak_exports_add_path_dir (FlatpakExports *exports,
const char *path);
gboolean flatpak_exports_add_path_expose (FlatpakExports *exports,
FlatpakFilesystemMode mode,
const char *path,
GError **error);
gboolean flatpak_exports_add_path_tmpfs (FlatpakExports *exports,
const char *path,
GError **error);
gboolean flatpak_exports_add_path_expose_or_hide (FlatpakExports *exports,
FlatpakFilesystemMode mode,
const char *path,
GError **error);
gboolean flatpak_exports_add_path_dir (FlatpakExports *exports,
const char *path,
GError **error);
gboolean flatpak_exports_path_is_visible (FlatpakExports *exports,
const char *path);

View File

@@ -1050,55 +1050,46 @@ _exports_path_expose (FlatpakExports *exports,
return TRUE;
}
void
flatpak_exports_add_path_expose (FlatpakExports *exports,
FlatpakFilesystemMode mode,
const char *path)
gboolean
flatpak_exports_add_path_expose (FlatpakExports *exports,
FlatpakFilesystemMode mode,
const char *path,
GError **error)
{
g_autoptr(GError) local_error = NULL;
g_return_if_fail (mode > FLATPAK_FILESYSTEM_MODE_NONE);
g_return_if_fail (mode <= FLATPAK_FILESYSTEM_MODE_LAST);
if (!_exports_path_expose (exports, mode, path, 0, &local_error))
g_debug ("Unable to %s: \"%s\": %s",
export_mode_to_verb (mode), path, local_error->message);
g_return_val_if_fail (mode > FLATPAK_FILESYSTEM_MODE_NONE, FALSE);
g_return_val_if_fail (mode <= FLATPAK_FILESYSTEM_MODE_LAST, FALSE);
return _exports_path_expose (exports, mode, path, 0, error);
}
void
flatpak_exports_add_path_tmpfs (FlatpakExports *exports,
const char *path)
gboolean
flatpak_exports_add_path_tmpfs (FlatpakExports *exports,
const char *path,
GError **error)
{
g_autoptr(GError) local_error = NULL;
if (!_exports_path_expose (exports, FAKE_MODE_TMPFS, path, 0, &local_error))
g_debug ("Unable to %s: \"%s\": %s",
export_mode_to_verb (FAKE_MODE_TMPFS), path, local_error->message);
return _exports_path_expose (exports, FAKE_MODE_TMPFS, path, 0, error);
}
void
flatpak_exports_add_path_expose_or_hide (FlatpakExports *exports,
FlatpakFilesystemMode mode,
const char *path)
gboolean
flatpak_exports_add_path_expose_or_hide (FlatpakExports *exports,
FlatpakFilesystemMode mode,
const char *path,
GError **error)
{
g_return_if_fail (mode >= FLATPAK_FILESYSTEM_MODE_NONE);
g_return_if_fail (mode <= FLATPAK_FILESYSTEM_MODE_LAST);
g_return_val_if_fail (mode >= FLATPAK_FILESYSTEM_MODE_NONE, FALSE);
g_return_val_if_fail (mode <= FLATPAK_FILESYSTEM_MODE_LAST, FALSE);
if (mode == FLATPAK_FILESYSTEM_MODE_NONE)
flatpak_exports_add_path_tmpfs (exports, path);
return flatpak_exports_add_path_tmpfs (exports, path, error);
else
flatpak_exports_add_path_expose (exports, mode, path);
return flatpak_exports_add_path_expose (exports, mode, path, error);
}
void
flatpak_exports_add_path_dir (FlatpakExports *exports,
const char *path)
gboolean
flatpak_exports_add_path_dir (FlatpakExports *exports,
const char *path,
GError **error)
{
g_autoptr(GError) local_error = NULL;
if (!_exports_path_expose (exports, FAKE_MODE_DIR, path, 0, &local_error))
g_debug ("Unable to %s: \"%s\": %s",
export_mode_to_verb (FAKE_MODE_DIR), path, local_error->message);
return _exports_path_expose (exports, FAKE_MODE_DIR, path, 0, error);
}
void

View File

@@ -734,6 +734,7 @@ test_full (void)
g_autofree gchar *create_dir = g_build_filename (subdir, "create-dir", NULL);
g_autofree gchar *create_dir2 = g_build_filename (subdir, "create-dir2", NULL);
gsize i;
gboolean ok;
glnx_shutil_rm_rf_at (-1, subdir, NULL, &error);
@@ -789,30 +790,55 @@ test_full (void)
FLATPAK_FILESYSTEM_MODE_READ_WRITE);
flatpak_exports_add_host_os_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY);
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_WRITE,
expose_rw);
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
expose_ro);
flatpak_exports_add_path_tmpfs (exports, hide_below_expose);
flatpak_exports_add_path_expose_or_hide (exports,
FLATPAK_FILESYSTEM_MODE_NONE,
hide);
flatpak_exports_add_path_expose_or_hide (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
dont_hide);
flatpak_exports_add_path_expose_or_hide (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
enoent);
flatpak_exports_add_path_expose_or_hide (exports,
FLATPAK_FILESYSTEM_MODE_READ_WRITE,
rel_link);
flatpak_exports_add_path_expose_or_hide (exports,
FLATPAK_FILESYSTEM_MODE_READ_WRITE,
abs_link);
flatpak_exports_add_path_dir (exports, create_dir);
flatpak_exports_add_path_dir (exports, create_dir2);
ok = flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_WRITE,
expose_rw, &error);
g_assert_no_error (error);
g_assert_true (ok);
ok = flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
expose_ro, &error);
g_assert_no_error (error);
g_assert_true (ok);
ok = flatpak_exports_add_path_tmpfs (exports, hide_below_expose, &error);
g_assert_no_error (error);
g_assert_true (ok);
ok = flatpak_exports_add_path_expose_or_hide (exports,
FLATPAK_FILESYSTEM_MODE_NONE,
hide, &error);
g_assert_no_error (error);
g_assert_true (ok);
ok = flatpak_exports_add_path_expose_or_hide (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
dont_hide, &error);
g_assert_no_error (error);
g_assert_true (ok);
ok = flatpak_exports_add_path_expose_or_hide (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
enoent, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
g_assert_false (ok);
g_clear_error (&error);
ok = flatpak_exports_add_path_expose_or_hide (exports,
FLATPAK_FILESYSTEM_MODE_READ_WRITE,
rel_link, &error);
g_assert_no_error (error);
g_assert_true (ok);
ok = flatpak_exports_add_path_expose_or_hide (exports,
FLATPAK_FILESYSTEM_MODE_READ_WRITE,
abs_link, &error);
g_assert_no_error (error);
g_assert_true (ok);
ok = flatpak_exports_add_path_dir (exports, create_dir, &error);
g_assert_no_error (error);
g_assert_true (ok);
ok = flatpak_exports_add_path_dir (exports, create_dir2, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
g_assert_false (ok);
g_clear_error (&error);
g_assert_cmpuint (flatpak_exports_path_get_mode (exports, expose_rw), ==,
FLATPAK_FILESYSTEM_MODE_READ_WRITE);
@@ -1233,6 +1259,34 @@ test_exports_debian_merged (void)
g_assert_cmpuint (i, ==, bwrap->argv->len);
}
static const struct
{
const char *tried;
const char *because;
}
reserved_filesystems[] =
{
{ "/app", "/app" },
{ "/app/foo", "/app" },
{ "/bin", "/bin" },
{ "/bin/sh", "/bin" },
{ "/dev", "/dev" },
{ "/etc", "/etc" },
{ "/etc/passwd", "/etc" },
{ "/lib", "/lib" },
{ "/lib/ld-linux.so.2", "/lib" },
{ "/lib64", "/lib64" },
{ "/lib64/ld-linux-x86-64.so.2", "/lib64" },
{ "/proc", "/proc" },
{ "/proc/1", "/proc" },
{ "/proc/sys/net", "/proc" },
{ "/sbin", "/sbin" },
{ "/sbin/ldconfig", "/sbin" },
{ "/usr", "/usr" },
{ "/usr/bin/env", "/usr" },
{ "/usr/foo/bar", "/usr" },
};
static void
test_exports_ignored (void)
{
@@ -1240,62 +1294,31 @@ test_exports_ignored (void)
g_autoptr(FlatpakExports) exports = flatpak_exports_new ();
gsize i;
/* These paths are chosen so that they probably exist, with the
* exception of /app */
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/app");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/etc");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/etc/passwd");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/usr");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/usr/bin/env");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/dev");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/dev/full");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/proc");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/proc/1");
for (i = 0; i < G_N_ELEMENTS (reserved_filesystems); i++)
{
const char *tried = reserved_filesystems[i].tried;
const char *because = reserved_filesystems[i].because;
g_autoptr(GError) error = NULL;
gboolean ok;
/* These probably exist, and are merged into /usr on systems with
* the /usr merge */
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/bin");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/bin/sh");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/lib");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/lib/ld-linux.so.2");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/lib64");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/lib64/ld-linux-x86-64.so.2");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/sbin");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/sbin/ldconfig");
ok = flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
tried,
&error);
g_assert_nonnull (error);
g_assert_nonnull (error->message);
g_test_message ("Trying to export %s -> %s", tried, error->message);
g_assert_false (ok);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTABLE_FILE))
{
g_autofree char *pattern = g_strdup_printf ("Path \"%s\" is reserved by Flatpak",
because);
g_test_message ("Expecting to see pattern: %s", pattern);
g_assert_nonnull (strstr (error->message, pattern));
}
}
flatpak_bwrap_add_arg (bwrap, "bwrap");
flatpak_exports_append_bwrap_args (exports, bwrap);
@@ -1344,35 +1367,71 @@ test_exports_unusual (void)
g_autoptr(FlatpakBwrap) bwrap = flatpak_bwrap_new (NULL);
g_autoptr(FlatpakExports) exports = NULL;
gsize i;
g_autoptr(GError) error = NULL;
gboolean ok;
exports = test_host_exports_setup (files,
FLATPAK_FILESYSTEM_MODE_NONE,
FLATPAK_FILESYSTEM_MODE_READ_ONLY);
flatpak_exports_set_test_flags (exports, FLATPAK_EXPORTS_TEST_FLAGS_AUTOFS);
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/broken-autofs");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/dangling-link");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/home/me");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/nonexistent");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/recursion");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/tmp");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_WRITE,
"/var/tmp");
flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"not-absolute");
ok = flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/broken-autofs", &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
g_test_message ("attempting to export /broken-autofs: %s", error->message);
g_assert_false (ok);
g_clear_error (&error);
ok = flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/dangling-link", &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
g_test_message ("attempting to export /dangling-link: %s", error->message);
g_assert_false (ok);
g_clear_error (&error);
ok = flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/home/me", &error);
g_assert_no_error (error);
g_assert_true (ok);
ok = flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/nonexistent", &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
g_test_message ("attempting to export /nonexistent: %s", error->message);
g_assert_false (ok);
g_clear_error (&error);
ok = flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/recursion", &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TOO_MANY_LINKS);
g_test_message ("attempting to export /recursion: %s", error->message);
g_assert_false (ok);
g_clear_error (&error);
ok = flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"/tmp", &error);
g_assert_no_error (error);
g_assert_true (ok);
ok = flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_WRITE,
"/var/tmp", &error);
g_assert_no_error (error);
g_assert_true (ok);
ok = flatpak_exports_add_path_expose (exports,
FLATPAK_FILESYSTEM_MODE_READ_ONLY,
"not-absolute", &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME);
g_test_message ("attempting to export not-absolute: %s", error->message);
g_assert_false (ok);
g_clear_error (&error);
test_host_exports_finish (exports, bwrap);
i = 0;
@@ -1401,6 +1460,9 @@ main (int argc, char *argv[])
{
int res;
/* Do not call setlocale() here: some tests look at untranslated error
* messages. */
isolated_test_dir_global_setup ();
g_test_init (&argc, &argv, NULL);