ex-container: Make /usr/etc/{,g}shadow user-readable

For the `ex container` case, there's no security issues here; one shouldn't be
doing user management in these roots at all.

This is for work on exporting `ex container` roots to OCI as non-root. Without
this fix, libostree just tries to `openat()` the object for export to tar, and
fails.

See also https://github.com/projectatomic/rpm-ostree/issues/1045

Closes: #1046
Approved by: jlebon
This commit is contained in:
Colin Walters 2017-10-10 11:10:48 -04:00 committed by Atomic Bot
parent 4a4f9952c2
commit 334f0b89be
4 changed files with 44 additions and 0 deletions

View File

@ -32,6 +32,7 @@
#include "rpmostree-util.h"
#include "rpmostree-core.h"
#include "rpmostree-libbuiltin.h"
#include "rpmostree-postprocess.h"
#include "rpmostree-rpm-util.h"
#include "rpmostree-unpacker.h"
@ -287,6 +288,9 @@ rpmostree_container_builtin_assemble (int argc,
NULL, RPMOSTREE_ASSEMBLE_TYPE_SERVER_BASE,
&commit, cancellable, error))
return EXIT_FAILURE;
if (!rpmostree_rootfs_postprocess_container (tmpdir.fd, cancellable, error))
return EXIT_FAILURE;
}
g_print ("Checking out %s @ %s...\n", name, commit);
@ -476,6 +480,9 @@ rpmostree_container_builtin_upgrade (int argc, char **argv,
&new_commit_checksum,
cancellable, error))
return EXIT_FAILURE;
if (!rpmostree_rootfs_postprocess_container (tmpdir.fd, cancellable, error))
return EXIT_FAILURE;
}
g_print ("Checking out %s @ %s...\n", name, new_commit_checksum);

View File

@ -1644,6 +1644,33 @@ rpmostree_prepare_rootfs_for_commit (int src_rootfs_dfd,
return TRUE;
}
/* Run through a standard set of postprocessing for "container"
* flows as used by `ex container`. Currently:
*
* - Make /usr/etc/{g,}shadow user readable
* See https://github.com/projectatomic/rpm-ostree/issues/1045
*/
gboolean
rpmostree_rootfs_postprocess_container (int rootfs_fd,
GCancellable *cancellable,
GError **error)
{
const char *shadow_paths[] = { "usr/etc/shadow", "usr/etc/gshadow" };
for (guint i = 0; i < G_N_ELEMENTS (shadow_paths); i++)
{
struct stat stbuf;
const char *path = shadow_paths[i];
if (!glnx_fstatat_allow_noent (rootfs_fd, path, &stbuf, AT_SYMLINK_NOFOLLOW, error))
return FALSE;
/* Silently ignore if it's not there, or isn't a regular file for some reason */
if (errno == ENOENT || !S_ISREG (stbuf.st_mode))
continue;
if (fchmodat (rootfs_fd, path, stbuf.st_mode | S_IRUSR, 0) < 0)
return glnx_throw_errno_prefix (error, "fchmodat");
}
return TRUE;
}
struct CommitThreadData {
volatile gint done;
off_t n_bytes;

View File

@ -52,6 +52,11 @@ rpmostree_rootfs_postprocess_common (int rootfs_fd,
GCancellable *cancellable,
GError **error);
gboolean
rpmostree_rootfs_postprocess_container (int rootfs_fd,
GCancellable *cancellable,
GError **error);
gboolean
rpmostree_prepare_rootfs_get_sepolicy (int dfd,
OstreeSePolicy **out_sepolicy,

View File

@ -3,6 +3,9 @@ set -xeuo pipefail
cd ${test_tmpdir}
dn=$(cd $(dirname $0) && pwd)
. ${dn}/../common/libtest-core.sh
cat >bash.conf <<EOF
[tree]
ref=bash
@ -11,3 +14,5 @@ repos=fedora;
EOF
rpm-ostree ex container assemble bash.conf
ostree --repo=repo ls bash /usr/etc/shadow > shadowls.txt
assert_file_has_content shadowls.txt '^-00400 .*/usr/etc/shadow'