upgrader: Add user-inaccessible private dir for rootfs checkouts

This is part of the saga of permissions and checkouts that
came about thinking about flatpak, but suid and world-writable dirs
are also an issue for us.

There's no reason to make suid binaries accessible temporarily
to users while we're computing a new root.  Similarly, we don't
want anyone to actually *write* to our temporary `/tmp`.  The
simple fix is to make an intermediate dir that's `0700`.

See: https://github.com/ostreedev/ostree/pull/909
See: https://github.com/flatpak/flatpak/pull/843

Closes: #821
Approved by: jlebon
This commit is contained in:
Colin Walters 2017-06-08 10:41:36 -04:00 committed by Atomic Bot
parent 69cc3a13a2
commit 5da409fcad
2 changed files with 20 additions and 2 deletions

View File

@ -24,8 +24,12 @@
/* Used by the upgrader to hold a strong ref temporarily to a base commit */
#define RPMOSTREE_TMP_BASE_REF "rpmostree/base/tmp"
/* Diretory that is defined to have 0700 mode always, used for checkouts */
#define RPMOSTREE_TMP_PRIVATE_DIR "extensions/rpmostree/private"
/* Where we check out a new rootfs */
#define RPMOSTREE_TMP_ROOTFS_DIR "extensions/rpmostree/commit"
#define RPMOSTREE_TMP_ROOTFS_DIR RPMOSTREE_TMP_PRIVATE_DIR "/commit"
/* The legacy dir, which we will just delete if we find it */
#define RPMOSTREE_OLD_TMP_ROOTFS_DIR "extensions/rpmostree/commit"
gboolean
rpmostree_syscore_cleanup (OstreeSysroot *sysroot,

View File

@ -443,11 +443,25 @@ checkout_base_tree (RpmOstreeSysrootUpgrader *self,
rpmostree_output_task_begin ("Checking out tree %.7s", self->base_revision);
int repo_dfd = ostree_repo_get_dfd (self->repo); /* borrowed */
/* Always delete this */
if (!glnx_shutil_rm_rf_at (repo_dfd, RPMOSTREE_OLD_TMP_ROOTFS_DIR,
cancellable, error))
return FALSE;
/* Make the parents with default mode */
if (!glnx_shutil_mkdir_p_at (repo_dfd,
dirname (strdupa (RPMOSTREE_TMP_ROOTFS_DIR)),
dirname (strdupa (RPMOSTREE_TMP_PRIVATE_DIR)),
0755, cancellable, error))
return FALSE;
/* And this dir should always be 0700, to ensure that when we checkout
* world-writable dirs like /tmp it's not accessible to unprivileged users.
*/
if (!glnx_shutil_mkdir_p_at (repo_dfd,
RPMOSTREE_TMP_PRIVATE_DIR,
0700, cancellable, error))
return FALSE;
/* delete dir in case a previous run didn't finish successfully */
if (!glnx_shutil_rm_rf_at (repo_dfd, RPMOSTREE_TMP_ROOTFS_DIR,
cancellable, error))