dir: Ensure ~/.local/share/flatpak is 0700

This goes into a big old topic about Unix homedir permissions; it's not uncommon
for general purpose OS vendors to have homedirs be 0755. In that case,
applications need to ensure confidentiality for data requiring it (classically
e.g. `~/.ssh`) by making the dirs `0700`.

While most of the data in the flatpak per-user dir probably isn't confidential
(debatably) we have a different issue; if container content includes suid or
world-writable files/dirs, then having that data accessible to other users
is obviously problematic.

We're going to fix flatpak/ostree to not create files with those modes
to begin with, but this simple fix closes off the attack route for
the per-user directory.

A different fix will be necessary for the system-wide repo.

See: https://github.com/flatpak/flatpak/pull/837
tingping/wmclass
Colin Walters 2017-06-08 10:24:48 -04:00 committed by Alexander Larsson
parent 4714f55ebd
commit daf36ba2af
1 changed files with 38 additions and 1 deletions

View File

@ -1347,7 +1347,44 @@ flatpak_dir_ensure_path (FlatpakDir *self,
GCancellable *cancellable,
GError **error)
{
return flatpak_mkdir_p (self->basedir, cancellable, error);
/* In the system case, we use default perms */
if (!self->user)
return flatpak_mkdir_p (self->basedir, cancellable, error);
else
{
/* First make the parent */
g_autoptr(GFile) parent = g_file_get_parent (self->basedir);
if (!flatpak_mkdir_p (parent, cancellable, error))
return FALSE;
glnx_fd_close int parent_dfd = -1;
if (!glnx_opendirat (AT_FDCWD, flatpak_file_get_path_cached (parent), TRUE,
&parent_dfd, error))
return FALSE;
g_autofree char *name = g_file_get_basename (self->basedir);
/* Use 0700 in the user case to neuter any suid or world-writable
* bits that happen to be in content; see
* https://github.com/flatpak/flatpak/pull/837
*/
if (mkdirat (parent_dfd, name, 0700) < 0)
{
if (errno == EEXIST)
{
/* And fix up any existing installs that had too-wide perms */
struct stat stbuf;
if (fstatat (parent_dfd, name, &stbuf, 0) < 0)
return glnx_throw_errno_prefix (error, "fstatat");
if (stbuf.st_mode & S_IXOTH)
{
if (fchmodat (parent_dfd, name, 0700, 0) < 0)
return glnx_throw_errno_prefix (error, "fchmodat");
}
}
else
return glnx_throw_errno_prefix (error, "mkdirat");
}
return TRUE;
}
}
/* Warning: This is not threadsafe, don't use in libflatpak */