From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Anthony Harivel <aharivel@redhat.com>
Cc: qemu-devel@nongnu.org, pbonzini@redhat.com, mtosatti@redhat.com
Subject: Re: [PATCH v2 2/3] tools: build qemu-vmsr-helper
Date: Wed, 1 Nov 2023 10:52:58 +0000 [thread overview]
Message-ID: <ZUIuCgtbT2Oj+w74@redhat.com> (raw)
In-Reply-To: <20231031144605.64822-3-aharivel@redhat.com>
On Tue, Oct 31, 2023 at 03:46:02PM +0100, Anthony Harivel wrote:
> Introduce a privileged helper to access RAPL MSR.
>
> The privileged helper tool, qemu-vmsr-helper, is designed to provide
> virtual machines with the ability to read specific RAPL (Running Average
> Power Limit) MSRs without requiring CAP_SYS_RAWIO privileges or relying
> on external, out-of-tree patches.
>
> The helper tool leverages Unix permissions and SO_PEERCRED socket
> options to enforce access control, ensuring that only processes
> explicitly requesting read access via readmsr() from a valid Thread ID
> can access these MSRs.
>
> The list of RAPL MSRs that are allowed to be read by the helper tool is
> defined in rapl-msr-index.h. This list corresponds to the RAPL MSRs that
> will be supported in the next commit titled "Add support for RAPL MSRs
> in KVM/QEMU."
>
> Signed-off-by: Anthony Harivel <aharivel@redhat.com>
> ---
> docs/tools/index.rst | 1 +
> docs/tools/qemu-vmsr-helper.rst | 89 ++++++
> meson.build | 5 +
> tools/i386/qemu-vmsr-helper.c | 507 ++++++++++++++++++++++++++++++++
> tools/i386/rapl-msr-index.h | 28 ++
> 5 files changed, 630 insertions(+)
> create mode 100644 docs/tools/qemu-vmsr-helper.rst
> create mode 100644 tools/i386/qemu-vmsr-helper.c
> create mode 100644 tools/i386/rapl-msr-index.h
>
> +/*
> + * Check if the TID that request the MSR read
> + * belongs to the peer. It should a TID of a vCPU.
> + */
> +static bool is_tid_present(pid_t pid, pid_t tid)
> +{
> + char pidStr[20];
> + char tidStr[20];
> +
> + snprintf(pidStr, sizeof(pidStr), "%d", pid);
> + snprintf(tidStr, sizeof(tidStr), "%d", tid);
> +
> + char pidPath[256];
> + char tidPath[256];
> +
> + snprintf(pidPath, sizeof(pidPath), "/proc/%s", pidStr);
> + snprintf(tidPath, sizeof(tidPath), "/proc/%s/task/%s", pidStr, tidStr);
> +
> + /* Check if the TID directory exists within the PID directory */
> + if (access(tidPath, F_OK) == 0) {
> + return true;
> + }
> +
> + return false;
> +}
> +
> +/*
> + * Only the RAPL MSR in target/i386/cpu.h are allowed
> + */
> +static bool is_msr_allowed(uint32_t reg)
> +{
> + switch (reg) {
> + case MSR_RAPL_POWER_UNIT:
> + case MSR_PKG_POWER_LIMIT:
> + case MSR_PKG_ENERGY_STATUS:
> + case MSR_PKG_POWER_INFO:
> + return true;
> + default:
> + return false;
> + }
> +}
> + /*
> + * Check peer credentials
> + * Only QEMU PID/TID are allowed
This says only QEMU is allowed
> + */
> + qio_channel_get_peercred(QIO_CHANNEL(client->ioc), &cred, &local_err);
> +
> + if (cred.pid == 0) {
> + if (local_err != NULL) {
> + error_report_err(local_err);
> + }
> + error_report("Failed to get peer credentials");
> + goto out;
> + }
> +
> + /*
> + * Read the requested MSR
> + * Only RAPL MSR in rapl-msr-index.h is allowed
> + */
> + r = qio_channel_read_all(QIO_CHANNEL(client->ioc),
> + (char *) &request, sizeof(request), NULL);
> + if (!is_msr_allowed(request[0]) || r < 0) {
> + error_report("Read request fail: %d, %d", request[0], request[1]);
> + goto out;
> + }
> +
> + vmsr = vmsr_read_msr(request[0], request[1]);
> +
> + if (!is_tid_present(cred.pid, request[2])) {
> + error_report("requested TID not in peer PID");
> + vmsr = 0;
> + }
This check is merely validating the the thread ID in the message
is a child of the process ID connected to the socket. Any process
on the entire host can satisfy this requirement.
I don't see what is limiting this to only QEMU as claimed earlier,
unless you're expecting the UNIX socket permissions to be such
that only processes under the qemu:qemu user:group pair can
access to the socket ? That would be a libvirt based permissions
assumption though.
> +
> + r = qio_channel_write_all(QIO_CHANNEL(client->ioc),
> + (char *) &vmsr, sizeof(vmsr), NULL);
> + if (r < 0) {
> + error_report("write vmsr failed");
> + goto out;
> + }
> +
> +out:
> + object_unref(OBJECT(client->ioc));
> + g_free(client);
> +}
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 :|
next prev parent reply other threads:[~2023-11-01 10:53 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-31 14:46 [PATCH v2 0/3] Add support for RAPL MSRs series Anthony Harivel
2023-10-31 14:46 ` [PATCH v2 1/3] qio: add support for SO_PEERCRED for socket channel Anthony Harivel
2023-11-01 10:20 ` Daniel P. Berrangé
2023-11-01 14:23 ` Paolo Bonzini
2023-10-31 14:46 ` [PATCH v2 2/3] tools: build qemu-vmsr-helper Anthony Harivel
2023-11-01 10:36 ` Daniel P. Berrangé
2023-11-01 10:52 ` Daniel P. Berrangé [this message]
2023-11-01 14:32 ` Paolo Bonzini
2023-10-31 14:46 ` [PATCH v2 3/3] Add support for RAPL MSRs in KVM/Qemu Anthony Harivel
2023-11-01 11:24 ` Daniel P. Berrangé
2023-11-01 14:33 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZUIuCgtbT2Oj+w74@redhat.com \
--to=berrange@redhat.com \
--cc=aharivel@redhat.com \
--cc=mtosatti@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.