[PATCH v2] virt-aa-helper: disallow graphics socket read permissions

Simon Arlott posted 1 patch 3 years, 10 months ago
Test syntax-check failed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/libvirt tags/patchew/3eb60829-6619-4e26-4886-bba458b5dd9e@0882a8b5-c6c3-11e9-b005-00805fc181fe
src/security/virt-aa-helper.c | 2 +-
tests/virt-aa-helper-test     | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
[PATCH v2] virt-aa-helper: disallow graphics socket read permissions
Posted by Simon Arlott 3 years, 10 months ago
The VM does not need read permission for its own sockets to create,
bind(), listen(), accept() connections or to recv(), send(), etc. on
those connections.

This was fixed in ab9569e5460d1e4737fe8b625c67687dc2204665
(virt-aa-helper: disallow VNC socket read permissions),
but then b6465e1aa49397367a9cd0f27110b9c2280a7385
(graphics: introduce new listen type 'socket')
and acc83afe333bfadd3f7f79091d38ca3d7da1eeb2
(acc83afe333bfadd3f7f79091d38ca3d7da1eeb2) reverted it.

Unless the read permission is omitted, VMs can connect to each other's
VNC/graphics sockets.

Signed-off-by: Simon Arlott <libvirt@octiron.net>
---
Updated version that changes the test case too.

 src/security/virt-aa-helper.c | 2 +-
 tests/virt-aa-helper-test     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 6e6dd1b1db..fddbdafc41 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -1053,7 +1053,7 @@ get_files(vahControl * ctl)
 
             if (listenObj.type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET &&
                 listenObj.socket &&
-                vah_add_file(&buf, listenObj.socket, "rw"))
+                vah_add_file(&buf, listenObj.socket, "w"))
                 goto cleanup;
         }
     }
diff --git a/tests/virt-aa-helper-test b/tests/virt-aa-helper-test
index 6a6703ecf5..a3b3c01163 100755
--- a/tests/virt-aa-helper-test
+++ b/tests/virt-aa-helper-test
@@ -370,7 +370,7 @@ sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" "$template_xml" > "$tes
 testme "0" "hugepages" "-r -u $valid_uuid -F /run/hugepages/kvm/\*\*" "$test_xml" "/run/hugepages/kvm/.*rwk,$"
 
 sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,<graphics.*>,<graphics type='vnc' socket='/var/lib/libvirt/qemu/myself.vnc'><listen type='address' address='0.0.0.0'/></graphics>,g" "$template_xml" > "$test_xml"
-testme "0" "vnc socket" "-r -u $valid_uuid" "$test_xml" "/var/lib/libvirt/qemu/myself.vnc.*rw,$"
+testme "0" "vnc socket" "-r -u $valid_uuid" "$test_xml" "/var/lib/libvirt/qemu/myself.vnc.*\s\+w,$"
 
 sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<input type='passthrough' bus='virtio'><source evdev='$disk2' /></input></devices>,g" "$template_xml" > "$test_xml"
 testme "0" "input dev passthrough" "-r -u $valid_uuid" "$test_xml" "$disk2.*rw,$"
-- 
2.17.1

-- 
Simon Arlott

Re: [PATCH v2] virt-aa-helper: disallow graphics socket read permissions
Posted by Christian Ehrhardt 3 years, 7 months ago
On Thu, May 28, 2020 at 12:45 PM Simon Arlott <libvirt@octiron.net> wrote:
>
> The VM does not need read permission for its own sockets to create,
> bind(), listen(), accept() connections or to recv(), send(), etc. on
> those connections.
>
> This was fixed in ab9569e5460d1e4737fe8b625c67687dc2204665
> (virt-aa-helper: disallow VNC socket read permissions),
> but then b6465e1aa49397367a9cd0f27110b9c2280a7385
> (graphics: introduce new listen type 'socket')
> and acc83afe333bfadd3f7f79091d38ca3d7da1eeb2
> (acc83afe333bfadd3f7f79091d38ca3d7da1eeb2) reverted it.
>
> Unless the read permission is omitted, VMs can connect to each other's
> VNC/graphics sockets.

As only the defined path from the XML is allowed that would only apply
if one specified the same path in each VM definition right?
That would be borderline to "intentionally configured that way".

> Signed-off-by: Simon Arlott <libvirt@octiron.net>
> ---
> Updated version that changes the test case too.
>
>  src/security/virt-aa-helper.c | 2 +-
>  tests/virt-aa-helper-test     | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
> index 6e6dd1b1db..fddbdafc41 100644
> --- a/src/security/virt-aa-helper.c
> +++ b/src/security/virt-aa-helper.c
[...]

>  <graphics type='vnc' socket='/var/lib/libvirt/qemu/myself.vnc'><listen type='address' address='0.0.0.0'/></graphics>

Isn't that option above converted to "-vnc unix:path"?
Hmm, no as ./tests/qemuxml2argvdata/graphics-vnc-remove-generated-socket.args
shows it is actually removed later.

But the attribute that virt-aa-helper parses in the lines you touched
is used for good cases as well, cases like these:
./tests/qemuxml2argvdata/graphics-vnc-socket-new-cmdline.args
./tests/qemuxml2argvdata/graphics-vnc-socket.args

In which case qemu would need to write to it as it is meant to [1]:
"... Rather than using listen/port, QEMU supports a socket attribute
for listening on a unix domain socket path Since 0.8.8 . ..."

An example would be:
./tests/qemuxml2argvdata/graphics-vnc-socket.xml-22-    <graphics type='vnc'>
./tests/qemuxml2argvdata/graphics-vnc-socket.xml:23:      <listen
type='socket' socket='/tmp/vnc.sock'/>
./tests/qemuxml2argvdata/graphics-vnc-socket.xml-24-    </graphics>
=>
./tests/qemuxml2argvdata/graphics-vnc-socket.args:27:-vnc unix:/tmp/vnc.sock \

And if I bluntly try that there are cases where qemu then creates that socket:
  $ qemu-system-x86_64 -vnc socket:/tmp/foobar
creates:
  srwxrwxr-x 1 paelzer paelzer 0 Sep  1 11:43 /tmp/foobar=

Therefore qemu would need the write permission to that value IMHO.
And as I said the concern of "VMs can connect to each other" would
only be true if the admin specifies the same path in each of them
intentionally.


[1]: https://libvirt.org/formatdomain.html#graphical-framebuffers

-- 
Christian Ehrhardt
Staff Engineer, Ubuntu Server
Canonical Ltd

Re: [PATCH v2] virt-aa-helper: disallow graphics socket read permissions
Posted by Daniel P. Berrangé 3 years, 7 months ago
On Tue, Sep 01, 2020 at 12:11:11PM +0200, Christian Ehrhardt wrote:
> On Thu, May 28, 2020 at 12:45 PM Simon Arlott <libvirt@octiron.net> wrote:
> >
> > The VM does not need read permission for its own sockets to create,
> > bind(), listen(), accept() connections or to recv(), send(), etc. on
> > those connections.
> >
> > This was fixed in ab9569e5460d1e4737fe8b625c67687dc2204665
> > (virt-aa-helper: disallow VNC socket read permissions),
> > but then b6465e1aa49397367a9cd0f27110b9c2280a7385
> > (graphics: introduce new listen type 'socket')
> > and acc83afe333bfadd3f7f79091d38ca3d7da1eeb2
> > (acc83afe333bfadd3f7f79091d38ca3d7da1eeb2) reverted it.
> >
> > Unless the read permission is omitted, VMs can connect to each other's
> > VNC/graphics sockets.

snip

> And as I said the concern of "VMs can connect to each other" would
> only be true if the admin specifies the same path in each of them
> intentionally.

Protecting against administrator mis-configurations is NOT a goal
of the security drivers. We're only aiming to protect against a
compromised QEMU in whatever configuration the admin requested.


Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|