checkout: Add SELinux labeling for checkout, use in deploy

This is a variant of the efforts in https://github.com/ostreedev/ostree/pull/741
Working on `rpm-ostree livefs`, I realized though I needed to just
check out *new* files directly into the live `/etc` (and possibly
delete obsolete files).

The way the current `/etc` merge works is fundamentally different from
that.  So my plan currently is to probably do something like:

 - Compute diff
 - Check out each *new* file individually (as a copy)
 - Optionally delete obsolete files

Also, a few other things become more important - in the current deploy code, we
copy all of the files, then relabel them. But we shouldn't expose to *live*
systems the race conditions of doing that, plus we should only relabel files we
checked out.

By converting the deploy's /etc code to use this, we fix the same TODO item
there around atomically having the label set up as we create files. And further,
if we kill the `/var` relabeling which I think is unnecessary since Anaconda
does it, we could delete large chunks of code there.

In the implementation, there are two types of things: regular files, and
symlinks. For regular files, in the `O_TMPFILE` case, we have the ability to
do *everything* atomically (including SELinux labeling) before linking it into
place. So let's just use that. For symlinks, we use `setfscreatecon()`.

Closes: #797
Approved by: jlebon
This commit is contained in:
Colin Walters authored and Atomic Bot committed 2017-04-25 16:52:33 +00:00
1 parent 654b0c4877
commit e8efd1c8dc
6 files changed
+232 -67

No files matched your search

+41
View File
@@ -730,3 +730,44 @@ _ostree_sepolicy_fscreatecon_clear (OstreeSepolicyFsCreatecon *con)
return;
ostree_sepolicy_fscreatecon_cleanup (NULL);
}
/*
* Given @xattrs, filter out `security.selinux`, and return
* a new GVariant without it. Supports @xattrs as %NULL to
* mean "no xattrs", and also returns %NULL if no xattrs
* would result (rather than a zero-length array).
*/
GVariant *
_ostree_filter_selinux_xattr (GVariant *xattrs)
{
if (!xattrs)
return NULL;
gboolean have_xattrs = FALSE;
GVariantBuilder builder;
guint n = g_variant_n_children (xattrs);
for (guint i = 0; i < n; i++)
{
const char *name = NULL;
g_autoptr(GVariant) value = NULL;
g_variant_get_child (xattrs, i, "(^&ay@ay)",
&name, &value);
if (strcmp (name, "security.selinux") == 0)
continue;
/* Initialize builder lazily */
if (!have_xattrs)
{
have_xattrs = TRUE;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)"));
}
g_variant_builder_add (&builder, "(@ay@ay)",
g_variant_new_bytestring (name),
value);
}
/* Canonicalize zero length to NULL for efficiency */
if (!have_xattrs)
return NULL;
return g_variant_ref_sink (g_variant_builder_end (&builder));
}