security: selinux: Handle security labelling of FD-passed images

Unfortunately unlike with DAC we can't simply ignore labelling for the
FD and it also influences the on-disk state.

Thus we need to relabel the FD and we also store the existing label in
cases when the user will request best-effort label replacement.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
Peter Krempa 2023-01-05 14:23:05 +01:00
parent 7fceb5e168
commit 6f3d13bfbd
3 changed files with 35 additions and 1 deletions

View File

@ -1399,6 +1399,7 @@ virStorageSourceFDTupleFinalize(GObject *object)
g_free(fdt->fds);
g_free(fdt->testfds);
g_free(fdt->selinuxLabel);
G_OBJECT_CLASS(vir_storage_source_fd_tuple_parent_class)->finalize(object);
}

View File

@ -269,6 +269,9 @@ struct _virStorageSourceFDTuple {
/* connection this FD tuple is associated with for auto-closing */
virConnect *conn;
/* original selinux label when we relabel the image */
char *selinuxLabel;
};
G_DECLARE_FINAL_TYPE(virStorageSourceFDTuple, vir_storage_source_fd_tuple, VIR, STORAGE_SOURCE_FD_TUPLE, GObject);

View File

@ -1741,6 +1741,19 @@ virSecuritySELinuxRestoreImageLabelSingle(virSecurityManager *mgr,
if (src->readonly || src->shared)
return 0;
if (virStorageSourceIsFD(src)) {
if (migrated)
return 0;
if (!src->fdtuple ||
!src->fdtuple->selinuxLabel ||
src->fdtuple->nfds == 0)
return 0;
ignore_value(virSecuritySELinuxFSetFilecon(src->fdtuple->fds[0],
src->fdtuple->selinuxLabel));
return 0;
}
/* If we have a shared FS and are doing migration, we must not change
* ownership, because that kills access on the destination host which is
@ -1888,7 +1901,24 @@ virSecuritySELinuxSetImageLabelInternal(virSecurityManager *mgr,
path = vfioGroupDev;
}
if (virStorageSourceIsFD(src)) {
/* We can only really do labelling when we have the FD as the path
* may not be accessible for us */
if (!src->fdtuple || src->fdtuple->nfds == 0)
return 0;
/* force a writable label for the image if requested */
if (src->fdtuple->writable && secdef->imagelabel)
use_label = secdef->imagelabel;
/* store the existing selinux label for the image */
if (!src->fdtuple->selinuxLabel)
fgetfilecon_raw(src->fdtuple->fds[0], &src->fdtuple->selinuxLabel);
ret = virSecuritySELinuxFSetFilecon(src->fdtuple->fds[0], use_label);
} else {
ret = virSecuritySELinuxSetFilecon(mgr, path, use_label, remember);
}
if (ret == 1 && !disk_seclabel) {
/* If we failed to set a label, but virt_use_nfs let us