From: Michael Bommarito <[email protected]> Sent: Thursday, July 9, 
2026 7:29 PM
> 
> The Hyper-V dynamic memory host supplies DM_UNBALLOON_REQUEST messages
> with a header size and a range_count field. balloon_down() trusts
> range_count and walks req->range_array without checking that the received
> message contains that many ranges.
> 
> A malformed host or backend message can therefore make the guest read
> past the received VMBus packet while freeing balloon ranges. Validate the
> received message size and reject range_count values that exceed the
> present range array before walking it.

Same comment applies here as I wrote for your proposed validations for
the Hyper-V mouse driver. The balloon driver also has .allowed_in_isolated
set to false, so it isn't loaded in a CoCo VM and it hasn't been hardened
for the "untrusted host" threat model.

Michael

> 
> Impact: A malicious Hyper-V host or backend can crash a guest by sending
> a short unballoon request with an oversized range_count.
> 
> Fixes: 9aa8b50b2b3d ("Drivers: hv: Add Hyper-V balloon driver")
> Cc: [email protected]
> Assisted-by: Codex:gpt-5-5-xhigh
> Signed-off-by: Michael Bommarito <[email protected]>
> ---
>  drivers/hv/hv_balloon.c | 26 ++++++++++++++++++++++++--
>  1 file changed, 24 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
> index a848400a59a2d..f5bc8c9fea7b9 100644
> --- a/drivers/hv/hv_balloon.c
> +++ b/drivers/hv/hv_balloon.c
> @@ -1337,8 +1337,23 @@ static void balloon_up(struct work_struct *dummy)
>       }
>  }
> 
> +static bool unballoon_request_valid(struct dm_unballoon_request *req,
> +                                 u32 msg_size)
> +{
> +     u32 max_ranges;
> +
> +     if (msg_size < sizeof(*req) || req->hdr.size < sizeof(*req) ||
> +         req->hdr.size > msg_size)
> +             return false;
> +
> +     max_ranges = (req->hdr.size - sizeof(*req)) /
> +                  sizeof(req->range_array[0]);
> +
> +     return req->range_count <= max_ranges;
> +}
> +
>  static void balloon_down(struct hv_dynmem_device *dm,
> -                      struct dm_unballoon_request *req)
> +                      struct dm_unballoon_request *req, u32 msg_size)
>  {
>       union dm_mem_page_range *range_array = req->range_array;
>       int range_count = req->range_count;
> @@ -1346,6 +1361,12 @@ static void balloon_down(struct hv_dynmem_device *dm,
>       int i;
>       unsigned int prev_pages_ballooned = dm->num_pages_ballooned;
> 
> +     if (!unballoon_request_valid(req, msg_size)) {
> +             pr_warn_ratelimited("Invalid unballoon request: size %u, header 
> size
> %u, range count %u\n",
> +                                 msg_size, req->hdr.size, req->range_count);
> +             return;
> +     }
> +
>       for (i = 0; i < range_count; i++) {
>               free_balloon_pages(dm, &range_array[i]);
>               complete(&dm_device.config_event);
> @@ -1527,7 +1548,8 @@ static void balloon_onchannelcallback(void *context)
> 
>                       dm->state = DM_BALLOON_DOWN;
>                       balloon_down(dm,
> -                                  (struct dm_unballoon_request 
> *)recv_buffer);
> +                                  (struct dm_unballoon_request *)recv_buffer,
> +                                  recvlen);
>                       break;
> 
>               case DM_MEM_HOT_ADD_REQUEST:
> --
> 2.53.0


Reply via email to