From: "Fabian Grünbichler" <f.gruenbichler@proxmox.com>
To: Proxmox VE development discussion <pve-devel@lists.proxmox.com>
Subject: Re: [pve-devel] [PATCH cluster v3 1/2] add CFS_IPC_GET_GUEST_CONFIG_PROPERTIES method
Date: Fri, 08 Apr 2022 11:01:47 +0200 [thread overview]
Message-ID: <1649407522.hmxw0c6ppz.astroid@nora.none> (raw)
In-Reply-To: <1649406844.4azt6nsvob.astroid@nora.none>
On April 8, 2022 10:40 am, Fabian Grünbichler wrote:
> On March 17, 2022 12:44 pm, Dominik Csapak wrote:
>> for getting multiple properties from the in memory config of the
>> guests. I added a new CSF_IPC_ call to maintain backwards compatibility.
>>
>> It basically behaves the same as
>> CFS_IPC_GET_GUEST_CONFIG_PROPERTY, but takes a list of properties
>> instead.
>>
>> The old way of getting a single property is now also done by
>> the new function.
>>
>> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
>
> one more small nit, otherwise this LGTM
>
obviously after hitting send I found another one :-P
>> ---
>> changes since v2:
>> * add 'a-z' check while parsing the properties, this way the later min/max
>> code works as intended
>>
>> data/src/cfs-ipc-ops.h | 2 +
>> data/src/server.c | 62 +++++++++++++++
>> data/src/status.c | 174 ++++++++++++++++++++++++++++-------------
>> data/src/status.h | 3 +
>> 4 files changed, 185 insertions(+), 56 deletions(-)
>>
>> diff --git a/data/src/cfs-ipc-ops.h b/data/src/cfs-ipc-ops.h
>> index 003e233..249308d 100644
>> --- a/data/src/cfs-ipc-ops.h
>> +++ b/data/src/cfs-ipc-ops.h
>> @@ -43,4 +43,6 @@
>>
>> #define CFS_IPC_VERIFY_TOKEN 12
>>
>> +#define CFS_IPC_GET_GUEST_CONFIG_PROPERTIES 13
>> +
>> #endif
>> diff --git a/data/src/server.c b/data/src/server.c
>> index 549788a..b9394c8 100644
>> --- a/data/src/server.c
>> +++ b/data/src/server.c
>> @@ -89,6 +89,13 @@ typedef struct {
>> char property[];
>> } cfs_guest_config_propery_get_request_header_t;
>>
>> +typedef struct {
>> + struct qb_ipc_request_header req_header;
>> + uint32_t vmid;
>> + uint8_t num_props;
>> + char props[]; /* list of \0 terminated properties */
>> +} cfs_guest_config_properties_get_request_header_t;
>> +
>> typedef struct {
>> struct qb_ipc_request_header req_header;
>> char token[];
>> @@ -348,6 +355,61 @@ static int32_t s1_msg_process_fn(
>>
>> result = cfs_create_guest_conf_property_msg(outbuf, memdb, rh->property, rh->vmid);
>> }
>> + } else if (request_id == CFS_IPC_GET_GUEST_CONFIG_PROPERTIES) {
>> +
>> + cfs_guest_config_properties_get_request_header_t *rh =
>> + (cfs_guest_config_properties_get_request_header_t *) data;
>> +
>> + int propslen = request_size - G_STRUCT_OFFSET(cfs_guest_config_properties_get_request_header_t, props);
so request_size is int32_t, and the offset is 32 + 32 (qb header) + 32 +
8 = 13 bytes, so propslen will always fit in an int and be positive.
>> +
>> + result = 0;
>> + if (rh->vmid < 100 && rh->vmid != 0) {
>> + cfs_debug("vmid out of range %u", rh->vmid);
>> + result = -EINVAL;
>> + } else if (rh->vmid >= 100 && !vmlist_vm_exists(rh->vmid)) {
>> + result = -ENOENT;
>> + } else if (propslen <= 1) {
>> + cfs_debug("propslen <= 1, %d", propslen);
>> + result = -EINVAL;
>> + } else {
>> + const char **properties = malloc(sizeof(char*) * rh->num_props);
>> + char *current = (rh->props);
>> + int remaining = propslen;
remaining starts positive
>> + for (uint8_t i = 0; i < rh->num_props; i++) {
>> + uint8_t proplen = strnlen(current, remaining);
this ain't no uint8_t ;) so this takes a size_t (positive int is fine
accordingly) and returns one. a property can be longer than 255 chars
though, which makes the assignment overflow and gives us a
wrong/truncated proplen
>> + if (proplen == 0) {
could trigger this if the overflow aligns right.
>> + cfs_debug("property length 0");
>> + result = -EINVAL;
>> + break;
>> + }
>> + if (proplen == remaining) {
can't be triggered by overflow since proplen must always be smaller than
remaining
>> + cfs_debug("property not \\0 terminated");
>> + result = -EINVAL;
>> + break;
>> + }
>> + if (current[0] < 'a' || current[0] > 'z') {
this could be triggered depending on how exactly proplen overflows / the
property gets truncated
>> + cfs_debug("property does not start with [a-z]");
>> + result = -EINVAL;
>> + break;
>> + }
>> + properties[i] = current;
>> + current[proplen] = '\0'; // ensure property is 0 terminated
truncates an overly long property
>> + remaining -= (proplen + 1);
>> + current += proplen + 1;
and we start the next iteration at the truncated position
>> + }
>> +
>> + if (remaining != 0) {
which likely makes us end up here (except if the msg was malformed with
not-null-terminated properties, in which case they might align again and
just their boundaries are wrong ;))
given that we assume remaining remains positive, and barring further
future bugs that invariant should hold (we start off positive, in each
iteration proplen must be < remaining to reach the subtraction which
therefore at most reduces remaining to 0), we could switch both
remaining and proplen to size_t ?
or if the/a limit on property length is actually desired, we should
explicitly check for that (propslen <= limit * count at the start, and
then in the loop body still get a size_t from strnlen and check that the
result is < limit)
>
>> + cfs_debug("leftover data after parsing %ul properties", rh->num_props);
>> + result = -EINVAL;
>> + }
>> +
>> + if (result == 0) {
>> + cfs_debug("cfs_get_guest_config_properties: basic valid checked, do request");
>> + result = cfs_create_guest_conf_properties_msg(outbuf, memdb, properties, rh->num_props, rh->vmid);
>> + }
>> +
>> + free(properties);
>> + }
>> } else if (request_id == CFS_IPC_VERIFY_TOKEN) {
>>
>> cfs_verify_token_request_header_t *rh = (cfs_verify_token_request_header_t *) data;
>
> [..]
>
prev parent reply other threads:[~2022-04-08 9:01 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-17 11:44 Dominik Csapak
2022-03-17 11:44 ` [pve-devel] [PATCH cluster v3 2/2] Cluster: add get_guest_config_properties Dominik Csapak
2022-04-08 8:40 ` [pve-devel] [PATCH cluster v3 1/2] add CFS_IPC_GET_GUEST_CONFIG_PROPERTIES method Fabian Grünbichler
2022-04-08 9:01 ` Fabian Grünbichler [this message]
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=1649407522.hmxw0c6ppz.astroid@nora.none \
--to=f.gruenbichler@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/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.