On Tue, May 24, 2022 at 11:50:50AM +0200, Michal Prívozník wrote:
On 5/23/22 18:30, Daniel P. Berrangé wrote:
> On Mon, May 09, 2022 at 05:02:17PM +0200, Michal Privoznik wrote:
>> Since the level of trust that QEMU has is the same level of trust
>> that helper processes have there's no harm in placing all of them
>> into the same group.
>
> This assumption feels like it might be a bit of a stretch. I
> recall discussing this with Paolo to some extent a long time
> back, but let me recap my understanding.
>
> IIUC, the attack scenario is that a guest vCPU thread is scheduled
> on a SMT sibling with another thread that is NOT running guest OS
> code. "another thread" in this context refers to many things
>
> - Random host OS processes
> - QEMU vCPU threads from a different geust
> - QEMU emulator threads from any guest
> - QEMU helper process threads from any guest
>
> Consider for example, if the QEMU emulator thread contains a password
> used for logging into a remote RBD/Ceph server. That is a secret
> credential that the guest OS should not have permission to access.
>
> Consider alternatively that the QEMU emulator is making a TLS connection
> to some service, and there are keys negotiated for the TLS session. While
> some of the data transmitted over the session is known to the guest OS,
> we shouldn't assume it all is.
>
> Now in the case of QEMU emulator threads I think you can make a somewhat
> decent case that we don't have to worry about it. Most of the keys/passwds
> are used once at cold boot, so there's no attack window for vCPUs at that
> point. There is a small window of risk when hotplugging. If someone is
> really concerned about this though, they shouldn't have let QEMU have
> these credentials in the first place, as its already vulnerable to a
> guest escape. eg use kernel RBD instead of letting QEMU directly login
> to RBD.
>
> IOW, on balance of probabilities it is reasonable to let QEMU emulator
> threads be in the same core scheduling domain as vCPU threads.
>
> In the case of external QEMU helper processes though, I think it is
> a far less clearcut decision. There are a number of reasons why helper
> processes are used, but at least one significant motivating factor is
> security isolation between QEMU & the helper - they can only communicate
> and share information through certain controlled mechanisms.
>
> With this in mind I think it is risky to assume that it is safe to
> run QEMU and helper processes in the same core scheduling group. At
> the same time there are likely cases where it is also just fine to
> do so.
>
> If we separate helper processes from QEMU vCPUs this is not as wasteful
> as it sounds. Some the helper processes are running trusted code, there
> is no need for helper processes from different guests to be isolated.
> They can all just live in the default core scheduling domain.
>
> I feel like I'm talking myself into suggesting the core scheduling
> host knob in qemu.conf needs to be more than just a single boolean.
> Either have two knobs - one to turn it on/off and one to control
> whether helpers are split or combined - or have one knob and make
> it an enumeration.
Seems reasonable. And the default should be QEMU's emulator + vCPU
threads in one sched group, and all helper processes in another, right?
Not quite. I'm suggesting that helper processes can remain in the
host's default core scheduling group, since the helpers are all
executing trusted machine code.
> One possible complication comes if we consider a guest that is
> pinned, but not on the fine grained per-vCPU basis.
>
> eg if guest is set to allow floating over a sub-set of host CPUs
> we need to make sure that it is possible to actually execute the
> guest still. ie if entire guest is pinned to 1 host CPU but our
> config implies use of 2 distinct core scheduling domains, we have
> an unsolvable constraint.
Do we? Since we're placing emulator + vCPUs into one group and helper
processes into another these would never run at the same time, but that
would be the case anyways - if emulator write()-s into a helper's socket
it would be blocked because the helper isn't running. This "bottleneck"
is result of pinning everything onto a single CPU and exists regardless
of scheduling groups.
The only case where scheduling groups would make the bottleneck worse is
if emulator and vCPUs were in different groups, but we don't intent to
allow that.
Do we actually pin the helper processes at all ?
I was thinking of a scenario where we implicitly pin helper processes to
the same CPUs as the emulator threads and/or QEMU process-global pinning
mask. eg
If we only had
<vcpu placement='static' cpuset="2-3"
current="1">2</vcpu>
Traditionally the emulator threads, i/o threads, vCPU threads will
all float across host CPUs 2 & 3. I was assuming we also placed
helper processes in these same 2 host CPUs. Not sure if that's right
or not. Assuming we do, then...
Lets say CPUs 2 & 3 are SMT siblings.
We have helper processes in the default core scheduling
domain and QEMU in a dedicated core scheduling domain. We
loose 100% of concurrency between the vCPUs and helper
processes.
With 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 :|