From 8ba5bda821b4733a606411cadc40f2b6b4bcc59c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 10 Oct 2018 17:42:13 -0400 Subject: [PATCH] core: Apply s{u,g}id consistently on checkout This is basically overriding what happens with `bare-user` mode OSTree repositories. I put a lot of thought into avoiding creating suid files with that mode. But today this creates a situation where if we don't have a devino cache, the file will lose its suid bits. In the end, since we're using the "inaccessible directory" pattern anyways for rpm-ostree on the host, we don't need to really worry about transient suid binaries. And similarly when we're run inside an existing container, that's also fine. Closes: #1591 Approved by: jlebon --- src/libpriv/rpmostree-core.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/libpriv/rpmostree-core.c b/src/libpriv/rpmostree-core.c index da8ee433..c55c48f5 100644 --- a/src/libpriv/rpmostree-core.c +++ b/src/libpriv/rpmostree-core.c @@ -3297,9 +3297,21 @@ apply_rpmfi_overrides (RpmOstreeContext *self, rpm_mode_t mode = rpmfiFMode (fi); rpmfileAttrs fattrs = rpmfiFFlags (fi); const gboolean is_ghost = fattrs & RPMFILE_GHOST; + /* If we hardlinked from a bare-user repo, we won't have these higher bits + * set. The intention there is to avoid having transient suid binaries + * exposed, but in practice today for rpm-ostree we use the "inaccessible + * directory" pattern in repo/tmp. + * + * Another thing we could do down the line is to not chown things on disk + * and instead pass this data down into the commit modifier. That's in + * fact how gnome-continuous always worked. + */ + const gboolean has_non_bare_user_mode = + (mode & (S_ISUID | S_ISGID | S_ISVTX)) > 0; if (g_str_equal (user, "root") && g_str_equal (group, "root") && + !has_non_bare_user_mode && !have_fcaps) continue; @@ -3424,9 +3436,10 @@ apply_rpmfi_overrides (RpmOstreeContext *self, } /* also reapply chmod since e.g. at least the setuid gets taken off */ - if (S_ISREG (stbuf.st_mode)) + if (S_ISREG (mode)) { - if (fchmodat (tmprootfs_dfd, fn, stbuf.st_mode, 0) != 0) + g_assert (S_ISREG (stbuf.st_mode)); + if (fchmodat (tmprootfs_dfd, fn, mode, 0) != 0) return glnx_throw_errno_prefix (error, "fchmodat(%s)", fn); } }