forked from Mirrors/flatpak-builder
Support defining read-only filesystem access
If you do something like "--filesystem=host:ro" you get a read-only mount of the specified filesystem location.tingping/wmclass
parent
612bf0d08c
commit
f5cadc018b
|
@ -469,17 +469,18 @@ usage (char **argv)
|
|||
|
||||
fprintf (stderr,
|
||||
" -a Specify path for application (mounted at /app)\n"
|
||||
" -b DEST[=SOURCE] Bind extra source path readonly into DEST\n"
|
||||
" -b DEST[=SOURCE] Bind extra source path read-only into DEST\n"
|
||||
" -B DEST[=SOURCE] Bind extra source path into DEST\n"
|
||||
" -M DEST[=SOURCE] Bind extra source path into DEST and remove original\n"
|
||||
" -d SOCKETPATH Use SOCKETPATH as dbus session bus\n"
|
||||
" -D SOCKETPATH Use SOCKETPATH as dbus system bus\n"
|
||||
" -e Make /app/exports writable\n"
|
||||
" -E Make /etc a pure symlink to /usr/etc\n"
|
||||
" -f Mount the host filesystems\n"
|
||||
" -F Mount the host filesystems\n"
|
||||
" -f Mount the host filesystems read-only\n"
|
||||
" -g Allow use of direct rendering graphics\n"
|
||||
" -F Mount the host filesystems read-only\n"
|
||||
" -H Mount the users home directory (implied by -f)\n"
|
||||
" -H Mount the users home directory\n"
|
||||
" -h Mount the users home directory read-only\n"
|
||||
" -i Share IPC namespace with session\n"
|
||||
" -I APPID Set app id (used to find app data)\n"
|
||||
" -l Lock .ref files in all mounts\n"
|
||||
|
@ -1565,7 +1566,7 @@ mount_extra_root_dirs (int readonly)
|
|||
}
|
||||
|
||||
static void
|
||||
create_homedir (int mount_real_home, const char *app_id)
|
||||
create_homedir (int mount_real_home, int mount_home_ro, const char *app_id)
|
||||
{
|
||||
const char *home;
|
||||
const char *relative_home;
|
||||
|
@ -1586,10 +1587,12 @@ create_homedir (int mount_real_home, const char *app_id)
|
|||
if (mount_real_home)
|
||||
{
|
||||
writable_home = home;
|
||||
if (bind_mount (writable_home, relative_home, BIND_RECURSIVE))
|
||||
if (bind_mount (writable_home, relative_home, BIND_RECURSIVE | (mount_home_ro ? BIND_READONLY : 0)))
|
||||
die_with_error ("unable to mount %s", home);
|
||||
}
|
||||
else if (app_id != NULL)
|
||||
|
||||
if (app_id != NULL &&
|
||||
(!mount_real_home || mount_home_ro))
|
||||
{
|
||||
app_id_dir = strconcat3 (home, "/.var/app/", app_id);
|
||||
if (stat (app_id_dir, &st) == 0 && S_ISDIR (st.st_mode))
|
||||
|
@ -2022,6 +2025,7 @@ main (int argc,
|
|||
bool mount_host_fs = FALSE;
|
||||
bool mount_host_fs_ro = FALSE;
|
||||
bool mount_home = FALSE;
|
||||
bool mount_home_ro = FALSE;
|
||||
bool lock_files = FALSE;
|
||||
bool writable = FALSE;
|
||||
bool writable_app = FALSE;
|
||||
|
@ -2044,7 +2048,7 @@ main (int argc,
|
|||
|
||||
clean_argv (argc, argv);
|
||||
|
||||
while ((c = getopt (argc, argv, "+inWwceEsfFHra:m:M:b:B:p:x:ly:d:D:v:I:gS:")) >= 0)
|
||||
while ((c = getopt (argc, argv, "+inWwceEsfFHhra:m:M:b:B:p:x:ly:d:D:v:I:gS:")) >= 0)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
|
@ -2110,11 +2114,11 @@ main (int argc,
|
|||
create_etc_dir = FALSE;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
case 'F':
|
||||
mount_host_fs = TRUE;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
case 'f':
|
||||
mount_host_fs = TRUE;
|
||||
mount_host_fs_ro = TRUE;
|
||||
break;
|
||||
|
@ -2127,6 +2131,11 @@ main (int argc,
|
|||
mount_home = TRUE;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
mount_home = TRUE;
|
||||
mount_home_ro = TRUE;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
ipc = TRUE;
|
||||
break;
|
||||
|
@ -2439,8 +2448,8 @@ main (int argc,
|
|||
bind_mount ("/run/media", "run/media", BIND_RECURSIVE | (mount_host_fs_ro ? BIND_READONLY : 0));
|
||||
}
|
||||
|
||||
if (!mount_host_fs)
|
||||
create_homedir (mount_home, app_id);
|
||||
if (!mount_host_fs || mount_host_fs_ro)
|
||||
create_homedir (mount_home, mount_home_ro, app_id);
|
||||
|
||||
if (mount_host_fs || mount_home)
|
||||
{
|
||||
|
@ -2461,7 +2470,7 @@ main (int argc,
|
|||
}
|
||||
|
||||
/* If the user has homedir access, also allow dconf run dir access */
|
||||
bind_mount (dconf_run_path, get_relative_path (dconf_run_path), 0);
|
||||
bind_mount (dconf_run_path, get_relative_path (dconf_run_path), BIND_READONLY);
|
||||
free (dconf_run_path);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,12 @@ typedef enum {
|
|||
XDG_APP_CONTEXT_SHARED_IPC = 1 << 1,
|
||||
} XdgAppContextShares;
|
||||
|
||||
typedef enum {
|
||||
XDG_APP_FILESYSTEM_MODE_READ_WRITE = 1,
|
||||
XDG_APP_FILESYSTEM_MODE_READ_ONLY = 2,
|
||||
} XdgAppFilesystemMode;
|
||||
|
||||
|
||||
/* Same order as enum */
|
||||
static const char *xdg_app_context_shares[] = {
|
||||
"network",
|
||||
|
@ -376,10 +382,36 @@ get_user_dir_from_string (const char *filesystem)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static char *
|
||||
parse_filesystem_flags (const char *filesystem, XdgAppFilesystemMode *mode)
|
||||
{
|
||||
gsize len = strlen (filesystem);
|
||||
|
||||
if (mode)
|
||||
*mode = XDG_APP_FILESYSTEM_MODE_READ_WRITE;
|
||||
|
||||
if (g_str_has_suffix (filesystem, ":ro"))
|
||||
{
|
||||
len -= 3;
|
||||
if (mode)
|
||||
*mode = XDG_APP_FILESYSTEM_MODE_READ_ONLY;
|
||||
}
|
||||
else if (g_str_has_suffix (filesystem, ":rw"))
|
||||
{
|
||||
len -= 3;
|
||||
if (mode)
|
||||
*mode = XDG_APP_FILESYSTEM_MODE_READ_WRITE;
|
||||
}
|
||||
|
||||
return g_strndup (filesystem, len);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
xdg_app_context_verify_filesystem (const char *filesystem,
|
||||
xdg_app_context_verify_filesystem (const char *filesystem_and_mode,
|
||||
GError **error)
|
||||
{
|
||||
char *filesystem = parse_filesystem_flags (filesystem_and_mode, NULL);
|
||||
|
||||
if (strcmp (filesystem, "host") == 0)
|
||||
return TRUE;
|
||||
if (strcmp (filesystem, "home") == 0)
|
||||
|
@ -400,14 +432,19 @@ static void
|
|||
xdg_app_context_add_filesystem (XdgAppContext *context,
|
||||
const char *what)
|
||||
{
|
||||
g_hash_table_insert (context->filesystems, g_strdup (what), GINT_TO_POINTER (1));
|
||||
XdgAppFilesystemMode mode;
|
||||
char *fs = parse_filesystem_flags (what, &mode);
|
||||
|
||||
g_hash_table_insert (context->filesystems, fs, GINT_TO_POINTER (mode));
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_app_context_remove_filesystem (XdgAppContext *context,
|
||||
const char *what)
|
||||
{
|
||||
g_hash_table_insert (context->filesystems, g_strdup (what), NULL);
|
||||
g_hash_table_insert (context->filesystems,
|
||||
parse_filesystem_flags (what, NULL),
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -650,7 +687,7 @@ static GOptionEntry context_options[] = {
|
|||
{ "nosocket", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_nosocket_cb, "Don't expose socket to app", "SOCKET" },
|
||||
{ "device", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_device_cb, "Expose device to app", "DEVICE" },
|
||||
{ "nodevice", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_nodevice_cb, "Don't expose device to app", "DEVICE" },
|
||||
{ "filesystem", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_filesystem_cb, "Expose filesystem to app", "FILESYSTEM" },
|
||||
{ "filesystem", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_filesystem_cb, "Expose filesystem to app (:ro for read-only)", "FILESYSTEM[:ro]" },
|
||||
{ "nofilesystem", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_nofilesystem_cb, "Don't expose filesystem to app", "FILESYSTEM" },
|
||||
{ "env", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_env_cb, "Set environment variable", "VAR=VALUE" },
|
||||
{ "own-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_own_name_cb, "Allow app to own name on the session bus", "DBUS_NAME" },
|
||||
|
@ -873,13 +910,17 @@ xdg_app_context_save_metadata (XdgAppContext *context,
|
|||
|
||||
if (g_hash_table_size (context->filesystems) > 0)
|
||||
{
|
||||
GPtrArray *array = g_ptr_array_new ();
|
||||
g_autoptr(GPtrArray) array = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
g_hash_table_iter_init (&iter, context->filesystems);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
if (value != NULL)
|
||||
g_ptr_array_add (array, key);
|
||||
XdgAppFilesystemMode mode = GPOINTER_TO_INT (value);
|
||||
|
||||
if (mode == XDG_APP_FILESYSTEM_MODE_READ_ONLY)
|
||||
g_ptr_array_add (array, g_strconcat (key, ":ro", NULL));
|
||||
else if (value != NULL)
|
||||
g_ptr_array_add (array, g_strdup (key));
|
||||
}
|
||||
|
||||
g_key_file_set_string_list (metakey,
|
||||
|
@ -1287,6 +1328,7 @@ xdg_app_run_add_environment_args (GPtrArray *argv_array,
|
|||
gboolean home_access = FALSE;
|
||||
GString *xdg_dirs_conf = NULL;
|
||||
char opts[16];
|
||||
XdgAppFilesystemMode fs_mode, home_mode;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
|
@ -1310,19 +1352,29 @@ xdg_app_run_add_environment_args (GPtrArray *argv_array,
|
|||
opts[i++] = 'g';
|
||||
}
|
||||
|
||||
if (g_hash_table_lookup (context->filesystems, "host"))
|
||||
fs_mode = (XdgAppFilesystemMode)g_hash_table_lookup (context->filesystems, "host");
|
||||
if (fs_mode != 0)
|
||||
{
|
||||
g_debug ("Allowing host-fs access");
|
||||
opts[i++] = 'f';
|
||||
if (fs_mode == XDG_APP_FILESYSTEM_MODE_READ_WRITE)
|
||||
opts[i++] = 'F';
|
||||
else
|
||||
opts[i++] = 'f';
|
||||
home_access = TRUE;
|
||||
}
|
||||
else if (g_hash_table_lookup (context->filesystems, "home"))
|
||||
|
||||
home_mode = (XdgAppFilesystemMode)g_hash_table_lookup (context->filesystems, "home");
|
||||
if (home_mode != 0)
|
||||
{
|
||||
g_debug ("Allowing homedir access");
|
||||
opts[i++] = 'H';
|
||||
if (home_mode == XDG_APP_FILESYSTEM_MODE_READ_WRITE)
|
||||
opts[i++] = 'H';
|
||||
else
|
||||
opts[i++] = 'h';
|
||||
home_access = TRUE;
|
||||
}
|
||||
else
|
||||
|
||||
if (!home_access)
|
||||
{
|
||||
/* Enable persistant mapping only if no access to real home dir */
|
||||
|
||||
|
@ -1351,20 +1403,24 @@ xdg_app_run_add_environment_args (GPtrArray *argv_array,
|
|||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
const char *filesystem = key;
|
||||
XdgAppFilesystemMode mode = GPOINTER_TO_INT(value);
|
||||
const char *mode_arg;
|
||||
|
||||
if (value == NULL ||
|
||||
strcmp (filesystem, "host") == 0 ||
|
||||
strcmp (filesystem, "home") == 0)
|
||||
continue;
|
||||
|
||||
if (mode == XDG_APP_FILESYSTEM_MODE_READ_WRITE)
|
||||
mode_arg = "-B";
|
||||
else
|
||||
mode_arg = "-b";
|
||||
|
||||
if (g_str_has_prefix (filesystem, "xdg-"))
|
||||
{
|
||||
const char *path;
|
||||
int dir = get_user_dir_from_string (filesystem);
|
||||
|
||||
if (home_access)
|
||||
continue;
|
||||
|
||||
if (dir < 0)
|
||||
{
|
||||
g_warning ("Unsupported xdg dir %s\n", filesystem);
|
||||
|
@ -1388,7 +1444,7 @@ xdg_app_run_add_environment_args (GPtrArray *argv_array,
|
|||
|
||||
g_string_append_printf (xdg_dirs_conf, "%s=\"%s\"\n", get_user_dir_config_key (dir), path);
|
||||
|
||||
g_ptr_array_add (argv_array, g_strdup ("-B"));
|
||||
g_ptr_array_add (argv_array, g_strdup (mode_arg));
|
||||
g_ptr_array_add (argv_array, g_strdup_printf ("%s", path));
|
||||
}
|
||||
}
|
||||
|
@ -1396,13 +1452,10 @@ xdg_app_run_add_environment_args (GPtrArray *argv_array,
|
|||
{
|
||||
g_autofree char *path = NULL;
|
||||
|
||||
if (home_access)
|
||||
continue;
|
||||
|
||||
path = g_build_filename (g_get_home_dir(), filesystem+2, NULL);
|
||||
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_ptr_array_add (argv_array, g_strdup ("-B"));
|
||||
g_ptr_array_add (argv_array, g_strdup (mode_arg));
|
||||
g_ptr_array_add (argv_array, g_strdup (path));
|
||||
}
|
||||
}
|
||||
|
@ -1410,7 +1463,7 @@ xdg_app_run_add_environment_args (GPtrArray *argv_array,
|
|||
{
|
||||
if (g_file_test (filesystem, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_ptr_array_add (argv_array, g_strdup ("-B"));
|
||||
g_ptr_array_add (argv_array, g_strdup (mode_arg));
|
||||
g_ptr_array_add (argv_array, g_strdup_printf ("%s", filesystem));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue