Commit Graph

41 Commits

Author SHA1 Message Date
Laine Stump
75056f61f1 security: make it possible to set SELinux label of child process from its binary
Normally when a child process is started by libvirt, the SELinux label
of that process is set to virtd_t (plus an MCS range). In at least one
case (passt) we need for the SELinux label of a child process label to
match the label that the binary would have transitioned to
automatically if it had been run standalone (in the case of passt,
that label is passt_t).

This patch modifies virSecuritySELinuxSetChildProcessLabel() (and all
the functions above it in the call chain) so that the toplevel
function can set a new argument "useBinarySpecificLabel" to true. If
it is true, then virSecuritySELinuxSetChildProcessLabel() will call
the new function virSecuritySELinuxContextSetFromFile(), which uses
the selinux library function security_compute_create() to determine
what would be the label of the new process if it had been run
standalone (rather than being run by libvirt) - the MCS range from the
normally-used label is added to this newly derived label, and that is
what is used for the new process rather than whatever is in the
domain's security label (which will usually be virtd_t).

In order to easily verify that nothing was broken by these changes to
the call chain, all callers currently set useBinarySpecificPath =
false, so all behavior should be completely unchanged. (The next
patch will set it to true only for the case of running passt.)

https://bugzilla.redhat.com/2172267
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2023-03-10 14:09:29 -05:00
Michal Privoznik
caa25f75cf qemu: Drop @cmdret argument from qemuSecurityCommandRun()
Every single caller of qemuSecurityCommandRun() calls the
function as:

  if (qemuSecurityCommandRun(..., &cmdret) < 0)
      goto cleanup;

  if (cmdret < 0)
      goto cleanup;

(modulo @exitstatus shenanigans)

Well, there's no need for such complication. There isn't a single
caller (and probably will never be (TM)), that would need to
distinguish the reason for the failure. Therefore,
qemuSecurityCommandRun() can be made to pass the retval of
virCommandRun() called under the hood.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2023-03-03 12:02:59 +01:00
Michal Privoznik
10f9cb7705 qemu_security: Drop qemuSecurityStartTPMEmulator()
After previous cleanup this function is no longer used and thus
can be dropped.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2023-01-03 17:19:22 +01:00
Michal Privoznik
bdbb8e7b00 qemu_security: Introduce qemuSecuritySetTPMLabels()
Now that we have qemuSecurityRestoreTPMLabels() we might as well
have qemuSecuritySetTPMLabels(). The aim here is to remove
qemuSecurityStartTPMEmulator() which couples two separate things
into a single function call.

Therefore, introduce qemuSecuritySetTPMLabels() which does only
set seclabels on the TPM state.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2023-01-03 17:19:22 +01:00
Michal Privoznik
51b92836ff qemu_security: Rename qemuSecurityCleanupTPMEmulator()
The qemuSecurityCleanupTPMEmulator() function calls
virSecurityManagerRestoreTPMLabels() and thus the proper name is
qemuSecurityRestoreTPMLabels(). Rename it.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2023-01-03 17:19:22 +01:00
Michal Privoznik
8d6e1f3764 qemu_security: Rework qemuSecurityCleanupTPMEmulator()
Currently, qemuSecurityCleanupTPMEmulator() returns nothing which
means a caller (well, there's only one - qemuExtTPMStop()) can't
produce a warning when restoring seclabels on TPM state failed.
True, qemuSecurityCleanupTPMEmulator() does report a warning
itself, but only in one specific error path.

Make the function return an integer, just like the rest of
qemuSecurity*Restore() functions.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2023-01-03 17:19:22 +01:00
Michal Privoznik
3c2e55c5ed qemu_tpm: Extend start/stop APIs
This is basically just a continuation of the previous commit.
Now that the security driver APIs have a boolean flag that
controls setting/restoring seclabel of either both TPM state and
log files, or just the log file, propagate this boolean into
those APIs that start/stop swtpm emulator. For now, just pass
true. The juicy bits are soon to come.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2022-12-05 10:40:52 +01:00
Peng Liang
bc16c1bcf6 qemu: Remove unused includes
Signed-off-by: Peng Liang <tcx4c70@gmail.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2022-06-16 06:43:57 +02:00
Michal Privoznik
55c3e969cf qemu_security: Drop qemuSecurityStartVhostUserGPU()
There's no real difference between
qemuSecurityStartVhostUserGPU() and qemuSecurityCommandRun(). The
latter is used more frequently while the former has just one
user. Therefore, drop the less frequently used one.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2022-05-09 16:17:00 +02:00
Jim Fehlig
2e8ebfe3fa qemu: Set label on vhostuser net device when hotplugging
Attaching a newly created vhostuser port to a VM fails due to an
apparmor denial

internal error: unable to execute QEMU command 'chardev-add': Failed
to bind socket to /run/openvswitch/vhu838c4d29-c9: Permission denied

In the case of a net device type VIR_DOMAIN_NET_TYPE_VHOSTUSER, the
underlying chardev is not labeled in qemuDomainAttachNetDevice prior
to calling qemuMonitorAttachCharDev.

A simple fix would be to call qemuSecuritySetChardevLabel using the
embedded virDomainChrSourceDef in the virDomainNetDef vhostuser data,
but this incurs the risk of incorrectly restoring the label. E.g.
consider the DAC driver behavior with a vhostuser net device, which
uses a socket for the chardev backend. The DAC driver uses XATTRS to
store original labelling information, but XATTRS are not compatible
with sockets. Without the original labelling information, the socket
labels will be restored with root ownership, preventing other
less-privileged processes from connecting to the socket.

This patch avoids overloading chardev labelling with vhostuser net
devices by introducing virSecurityManager{Set,Restore}NetdevLabel,
which is currently only implemented for the apparmor driver. The
new APIs are then used to set and restore labels for the vhostuser
net devices.

Signed-off-by: Jim Fehlig <jfehlig@suse.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2021-08-26 16:06:45 -06:00
Michal Privoznik
c8238579fb lib: Drop internal virXXXPtr typedefs
Historically, we declared pointer type to our types:

  typedef struct _virXXX virXXX;
  typedef virXXX *virXXXPtr;

But usefulness of such declaration is questionable, at best.
Unfortunately, we can't drop every such declaration - we have to
carry some over, because they are part of public API (e.g.
virDomainPtr). But for internal types - we can do drop them and
use what every other C project uses 'virXXX *'.

This change was generated by a very ugly shell script that
generated sed script which was then called over each file in the
repository. For the shell script refer to the cover letter:

https://listman.redhat.com/archives/libvir-list/2021-March/msg00537.html

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2021-04-13 17:00:38 +02:00
Michal Privoznik
77ef118456 qemu_security: Complete renaming of virSecurityManagerSetAllLabel() argument
Just like in the previous commit, the stdin_path argument of
virSecurityManagerSetAllLabel() is renamed to incomingPath.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
2020-07-10 14:21:35 +02:00
Michal Privoznik
7e235954e5 Revert "qemuSecurityDomainRestorePathLabel: Introduce @ignoreNS argument"
The only consumer was removed in the previous commit.

This reverts commit f03a38bd1d.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
2020-07-10 14:18:50 +02:00
Michal Privoznik
e69df41b6d qemu_security: Implement virSecurityManager{Set,Restore}SavedStateLabel
These APIs don't use namespaces because the
virSecurityManagerSetSavedStateLabel() runs
when the namespace doesn't exist yet and thus
the virSecurityManagerRestoreSavedStateLabel()
has to run without namespace too.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
2020-07-10 14:16:27 +02:00
Michal Privoznik
f03a38bd1d qemuSecurityDomainRestorePathLabel: Introduce @ignoreNS argument
In a few cases we might set seclabels on a path outside of
namespaces. For instance, when restoring a domain from a file,
the file is opened, relabelled and only then the namespace is
created and the FD is passed to QEMU (see v6.3.0-rc1~108 for more
info). Therefore, when restoring the label on the restore file,
we must ignore domain namespaces and restore the label directly
in the host.

This bug demonstrates itself when restoring a domain from a block
device. We don't create the block device inside the domain
namespace and thus the following error is reported at the end of
(otherwise successful) restore:

error : virProcessRunInFork:1236 : internal error: child reported (status=125): unable to stat: /dev/sda: No such file or directory
error : virProcessRunInFork:1240 : unable to stat: /dev/sda: No such file or directory

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
2020-06-18 13:55:40 +02:00
Michal Privoznik
6a0eaebaaf qemu: Rename qemuSecurityRestoreSavedStateLabel()
The function calls virSecurityManagerDomainRestorePathLabel()
after all.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
2020-06-18 13:53:16 +02:00
Michal Privoznik
3cc557c7fa qemu: Drop unused qemuSecuritySetSavedStateLabel()
After previous commit this function is used no more.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
2020-06-18 13:51:28 +02:00
Michal Privoznik
13eb6c1468 qemu: Tell secdrivers which images are top parent
When preparing images for block jobs we modify their seclabels so
that QEMU can open them. However, as mentioned in the previous
commit, secdrivers base some it their decisions whether the image
they are working on is top of of the backing chain. Fortunately,
in places where we call secdrivers we know this and the
information can be passed to secdrivers.

The problem is the following: after the first blockcommit from
the base to one of the parents the XATTRs on the base image are
not cleared and therefore the second attempt to do another
blockcommit fails. This is caused by blockcommit code calling
qemuSecuritySetImageLabel() over the base image, possibly
multiple times (to ensure RW/RO access). A naive fix would be to
call the restore function. But this is not possible, because that
would deny QEMU the access to the base image.  Fortunately, we
can use the fact that seclabels are remembered only for the top
of the backing chain and not for the rest of the backing chain.
And thanks to the previous commit we can tell secdrivers which
images are top of the backing chain.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1803551

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2020-03-09 14:14:55 +01:00
Michal Privoznik
458d0a8c52 security: Pass @migrated to virSecurityManagerSetAllLabel
In upcoming commits, virSecurityManagerSetAllLabel() will perform
rollback in case of failure by calling
virSecurityManagerRestoreAllLabel(). But in order to do that, the
former needs to have @migrated argument so that it can be passed
to the latter.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Cole Robinson <crobinso@redhat.com>
2019-10-14 17:14:13 +02:00
Marc-André Lureau
019db0d944 qemu: add qemuSecurityStartVhostUserGPU helper
See function documentation. Used in a following patch.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Cole Robinson <crobinso@redhat.com>
2019-09-24 13:19:08 -04:00
Marc-André Lureau
e595c4e916 qemu-security: add qemuSecurityCommandRun()
Add a generic way to run a command through the security management.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2019-09-06 12:47:47 +02:00
Michal Privoznik
706e68237f qemu_security: Implement qemuSecurityMoveImageMetadata
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Cole Robinson <crobinso@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2019-07-03 08:36:04 +02:00
Jonathon Jongsma
5dad4b5d93 src/qemu: use #pragma once in headers
Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
2019-06-19 17:12:30 +02:00
Peter Krempa
787e4a3dc8 qemu: security: Replace and remove qemuSecurity[Set|Restore]DiskLabel
The same can be achieved by using qemuSecurity[Set|Restore]ImageLabel.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
2019-01-30 17:20:38 +01:00
Peter Krempa
81594afb05 qemu: security: Add 'backingChain' flag to qemuSecurity[Set|Restore]ImageLabel
The flag will control the VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN
flag of the security driver image labeling APIs.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
2019-01-30 17:20:38 +01:00
Daniel P. Berrangé
568a417224 Enforce a standard header file guard symbol name
Require that all headers are guarded by a symbol named

  LIBVIRT_$FILENAME

where $FILENAME is the uppercased filename, with all characters
outside a-z changed into '_'.

Note we do not use a leading __ because that is technically a
namespace reserved for the toolchain.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-12-14 10:47:13 +00:00
Daniel P. Berrangé
600462834f Remove all Author(s): lines from source file headers
In many files there are header comments that contain an Author:
statement, supposedly reflecting who originally wrote the code.
In a large collaborative project like libvirt, any non-trivial
file will have been modified by a large number of different
contributors. IOW, the Author: comments are quickly out of date,
omitting people who have made significant contribitions.

In some places Author: lines have been added despite the person
merely being responsible for creating the file by moving existing
code out of another file. IOW, the Author: lines give an incorrect
record of authorship.

With this all in mind, the comments are useless as a means to identify
who to talk to about code in a particular file. Contributors will always
be better off using 'git log' and 'git blame' if they need to  find the
author of a particular bit of code.

This commit thus deletes all Author: comments from the source and adds
a rule to prevent them reappearing.

The Copyright headers are similarly misleading and inaccurate, however,
we cannot delete these as they have legal meaning, despite being largely
inaccurate. In addition only the copyright holder is permitted to change
their respective copyright statement.

Reviewed-by: Erik Skultety <eskultet@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-12-13 16:08:38 +00:00
Michal Privoznik
592ed505e1 qemu_tpm: Pass virDomainObjPtr instead of virDomainDefPtr
The TPM code currently accepts pointer to a domain definition.
This is okay for now, but in near future the security driver APIs
it calls will require domain object. Therefore, change the TPM
code to accept the domain object pointer.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
2018-11-16 13:42:38 +01:00
Erik Skultety
5165ff0971 src: More cleanup of some system headers already contained in internal.h
All of the ones being removed are pulled in by internal.h. The only
exception is sanlock which expects the application to include <stdint.h>
before sanlock's headers, because sanlock prototypes use fixed width
int, but they don't include stdint.h themselves, so we have to leave
that one in place.

Signed-off-by: Erik Skultety <eskultet@redhat.com>
Acked-by: Michal Privoznik <mprivozn@redhat.com>
2018-09-20 10:16:39 +02:00
Michal Privoznik
ccafaacd61 qemu_security: Require full wrappers for APIs that might touch a file
In the future, the transactions are not going to be optional and
they will be run regardless of domain using namespace to collect
list of paths to be relabeled.

To make sure there won't be an API that goes behind transaction
code back update the comment that serves as decision manual
whether an API must be fully implemented or plain #define is
sufficient.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
2018-09-17 10:58:17 +02:00
Michal Privoznik
e2c23982dd qemu_security: Fully implement qemuSecurity{Set,Restore}SavedStateLabel
Even though the current use of the functions does not require full
implementation with transactions (none of the callers passes a path
somewhere under /dev), it doesn't hurt either. Moreover, in
future patches the paradigm is going to shift so that any API
that touches a file is required to use transactions.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
2018-09-17 10:58:17 +02:00
Michal Privoznik
da24db2d30 qemu_security: Fully implement qemuSecurityDomainSetPathLabel
Even though the current use of the function does not require full
implementation with transactions (none of the callers pass a path
somewhere under /dev), it doesn't hurt either. Moreover, in
future patches the paradigm is going to shift so that any API
that touches a file is required to use transactions.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
2018-09-17 10:58:17 +02:00
Stefan Berger
2fc665bb11 security: Label the external swtpm with SELinux labels
In this patch we label the swtpm process with SELinux labels. We give it the
same label as the QEMU process has. We label its state directory and files
as well. We restore the old security labels once the swtpm has terminated.

The file and process labels now look as follows:

Directory: /var/lib/libvirt/swtpm

[root@localhost swtpm]# ls -lZ
total 4
rwx------. 2 tss  tss  system_u:object_r:svirt_image_t:s0:c254,c932 4096 Apr  5 16:46 testvm

[root@localhost testvm]# ls -lZ
total 8
-rw-r--r--. 1 tss tss system_u:object_r:svirt_image_t:s0:c254,c932 3648 Apr  5 16:46 tpm-00.permall

The log in /var/log/swtpm/libvirt/qemu is labeled as follows:

-rw-r--r--. 1 tss tss system_u:object_r:svirt_image_t:s0:c254,c932 2237 Apr  5 16:46 vtpm.log

[root@localhost 485d0004-a48f-436a-8457-8a3b73e28567]# ps auxZ | grep swtpm | grep ctrl | grep -v grep
system_u:system_r:svirt_t:s0:c254,c932 tss 25664 0.0  0.0 28172  3892 ?        Ss   16:57   0:00 /usr/bin/swtpm socket --daemon --ctrl type=unixio,path=/var/run/libvirt/qemu/swtpm/testvm-swtpm.sock,mode=0660 --tpmstate dir=/var/lib/libvirt/swtpm/testvm/tpm1.2 --log file=/var/log/swtpm/libvirt/qemu/testvm-swtpm.log

[root@localhost 485d0004-a48f-436a-8457-8a3b73e28567]# ps auxZ | grep qemu | grep tpm | grep -v grep
system_u:system_r:svirt_t:s0:c254,c932 qemu 25669 99.0  0.0 3096704 48500 ?    Sl   16:57   3:28 /bin/qemu-system-x86_64 [..]

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2018-06-06 10:48:41 -04:00
Pavel Hrdina
1c57eea362 qemu: fix security labeling for attach/detach of char devices
Commit e93d844b90 was not enough to fix the permission denied
issue.  We need to apply security labels as well.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1465833

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
2017-12-05 13:54:48 +01:00
Ján Tomko
c4c7a18c4b qemu: functions for dealing with input device namespaces and labels
Introudce functions that will let us create the evdevs in namespaces
and label the devices on input device hotplug/hotunplug.
2017-11-24 17:38:51 +01:00
Michal Privoznik
78612aa597 qemu_hotplug: Relabel memdev
Now that we have APIs for relabel memdevs on hotplug, fill in the
missing implementation in qemu hotplug code.

The qemuSecurity wrappers might look like overkill for now,
because qemu namespace code does not deal with the nvdimms yet.
Nor does our cgroup code.  But hey, there's cgroup_device_acl
variable in qemu.conf. If users add their /dev/pmem* device in
there, the device is allowed in cgroups and created in the
namespace so they can successfully passthrough it to the domain.
It doesn't look like overkill after all, does it?

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 16:55:23 +01:00
Michal Privoznik
4da534c0b9 qemu: Enforce qemuSecurity wrappers
Now that we have some qemuSecurity wrappers over
virSecurityManager APIs, lets make sure everybody sticks with
them. We have them for a reason and calling virSecurityManager
API directly instead of wrapper may lead into accidentally
labelling a file on the host instead of namespace.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-06 08:54:28 +01:00
Michal Privoznik
c2130c0d47 qemu_security: Introduce ImageLabel APIs
Just like we need wrappers over other virSecurityManager APIs, we
need one for virSecurityManagerSetImageLabel and
virSecurityManagerRestoreImageLabel. Otherwise we might end up
relabelling device in wrong namespace.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-09 08:04:57 +01:00
Michal Privoznik
6e57492839 qemu: Manage /dev entry on hostdev hotplug
When attaching a device to a domain that's using separate mount
namespace we must maintain /dev entries in order for qemu process
to see them.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2016-12-15 09:25:16 +01:00
Michal Privoznik
81df21507b qemu: Manage /dev entry on disk hotplug
When attaching a device to a domain that's using separate mount
namespace we must maintain /dev entries in order for qemu process
to see them.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2016-12-15 09:25:16 +01:00
Michal Privoznik
eadaa97548 qemu: Enter the namespace on relabelling
Instead of trying to fix our security drivers, we can use a
simple trick to relabel paths in both namespace and the host.
I mean, if we enter the namespace some paths are still shared
with the host so any change done to them is visible from the host
too.
Therefore, we can just enter the namespace and call
SetAllLabel()/RestoreAllLabel() from there. Yes, it has slight
overhead because we have to fork in order to enter the namespace.
But on the other hand, no complexity is added to our code.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2016-12-15 09:25:16 +01:00