KVM: Reject device ioctls from processes other than the VM’s creator [Linux 3.16.72]

This Linux kernel change "KVM: Reject device ioctls from processes other than the VM’s creator" is included in the Linux 3.16.72 release. This change is authored by Sean Christopherson <sean.j.christopherson [at] intel.com> on Fri Feb 15 12:48:39 2019 -0800. The commit for this change in Linux stable tree is e62b3b7 (patch) which is from upstream commit ddba918. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream ddba918.

KVM: Reject device ioctls from processes other than the VM's creator

commit ddba91801aeb5c160b660caed1800eb3aef403f8 upstream.

KVM's API requires thats ioctls must be issued from the same process
that created the VM.  In other words, userspace can play games with a
VM's file descriptors, e.g. fork(), SCM_RIGHTS, etc..., but only the
creator can do anything useful.  Explicitly reject device ioctls that
are issued by a process other than the VM's creator, and update KVM's
API documentation to extend its requirements to device ioctls.

Fixes: 852b6d57dc7f ("kvm: add device control API")
Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>

There are 19 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 Documentation/virtual/kvm/api.txt | 16 +++++++++++-----
 virt/kvm/kvm_main.c               |  3 +++
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index e86da43..fcafeed 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -13,7 +13,7 @@ of a virtual machine.  The ioctls belong to three classes

  - VM ioctls: These query and set attributes that affect an entire virtual
    machine, for example memory layout.  In addition a VM ioctl is used to
-   create virtual cpus (vcpus).
+   create virtual cpus (vcpus) and devices.

    Only run VM ioctls from the same process (address space) that was used
    to create the VM.
@@ -24,6 +24,11 @@ of a virtual machine.  The ioctls belong to three classes
    Only run vcpu ioctls from the same thread that was used to create the
    vcpu.

+ - device ioctls: These query and set attributes that control the operation
+   of a single device.
+
+   device ioctls must be issued from the same process (address space) that
+   was used to create the VM.

 2. File descriptors
 -------------------
@@ -32,10 +37,11 @@ The kvm API is centered around file descriptors.  An initial
 open("/dev/kvm") obtains a handle to the kvm subsystem; this handle
 can be used to issue system ioctls.  A KVM_CREATE_VM ioctl on this
 handle will create a VM file descriptor which can be used to issue VM
-ioctls.  A KVM_CREATE_VCPU ioctl on a VM fd will create a virtual cpu
-and return a file descriptor pointing to it.  Finally, ioctls on a vcpu
-fd can be used to control the vcpu, including the important task of
-actually running guest code.
+ioctls.  A KVM_CREATE_VCPU or KVM_CREATE_DEVICE ioctl on a VM fd will
+create a virtual cpu or device and return a file descriptor pointing to
+the new resource.  Finally, ioctls on a vcpu or device fd can be used
+to control the vcpu or device.  For vcpus, this includes the important
+task of actually running guest code.

 In general file descriptors can be migrated among processes by means
 of fork() and the SCM_RIGHTS facility of unix domain socket.  These
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index ad0c85a6..cc0b4c5 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2240,6 +2240,9 @@ static long kvm_device_ioctl(struct file *filp, unsigned int ioctl,
 {
    struct kvm_device *dev = filp->private_data;

+   if (dev->kvm->mm != current->mm)
+       return -EIO;
+
    switch (ioctl) {
    case KVM_SET_DEVICE_ATTR:
        return kvm_device_ioctl_attr(dev, dev->ops->set_attr, arg);

Leave a Reply

Your email address will not be published. Required fields are marked *