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
This commit is contained in:
Colin Walters 2018-10-10 17:42:13 -04:00 committed by Atomic Bot
parent 4b6040b740
commit 8ba5bda821

View File

@ -3297,9 +3297,21 @@ apply_rpmfi_overrides (RpmOstreeContext *self,
rpm_mode_t mode = rpmfiFMode (fi); rpm_mode_t mode = rpmfiFMode (fi);
rpmfileAttrs fattrs = rpmfiFFlags (fi); rpmfileAttrs fattrs = rpmfiFFlags (fi);
const gboolean is_ghost = fattrs & RPMFILE_GHOST; 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") && if (g_str_equal (user, "root") &&
g_str_equal (group, "root") && g_str_equal (group, "root") &&
!has_non_bare_user_mode &&
!have_fcaps) !have_fcaps)
continue; continue;
@ -3424,9 +3436,10 @@ apply_rpmfi_overrides (RpmOstreeContext *self,
} }
/* also reapply chmod since e.g. at least the setuid gets taken off */ /* 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); return glnx_throw_errno_prefix (error, "fchmodat(%s)", fn);
} }
} }