From: Claude Code Review Bot <claude-review@example.com>
To: dri-devel-reviews@example.com
Subject: Claude review: drm/hyperv: validate VMBus packet size in receive callback
Date: Mon, 25 May 2026 19:37:10 +1000 [thread overview]
Message-ID: <review-patch2-6e5d1d57a3afc4c5ea0d2a3d62be58c90741a869.1779396074.git.me@berkoc.com> (raw)
In-Reply-To: <6e5d1d57a3afc4c5ea0d2a3d62be58c90741a869.1779396074.git.me@berkoc.com>
Patch Review
**Verdict: Good. Well-reasoned defense-in-depth.**
**Header size check** — Correct. The minimum `hdr_size` of `sizeof(struct pipe_msg_hdr) + sizeof(struct synthvid_msg_hdr)` = 16 bytes ensures `msg->vid_hdr.type` is safe to read before the type dispatch:
```c
hdr_size = sizeof(struct pipe_msg_hdr) +
sizeof(struct synthvid_msg_hdr);
if (bytes_recvd < hdr_size) {
drm_err_ratelimited(&hv->dev,
"synthvid packet too small for header: %u\n",
bytes_recvd);
return;
}
```
**Per-type payload validation** — The switch inside the completion block is the right structure. Each response type gets its own minimum size:
- `SYNTHVID_VERSION_RESPONSE`: `hdr_size + sizeof(struct synthvid_version_resp)` = 22 bytes
- `SYNTHVID_VRAM_LOCATION_ACK`: `hdr_size + sizeof(struct synthvid_vram_location_ack)` = 24 bytes
- `SYNTHVID_FEATURE_CHANGE`: `hdr_size + sizeof(struct synthvid_feature_change)` = 20 bytes
**Variable-length SYNTHVID_RESOLUTION_RESPONSE** — This is the most complex case and it's handled well. The two-step validation is correct:
```c
case SYNTHVID_RESOLUTION_RESPONSE:
need += offsetof(struct synthvid_supported_resolution_resp,
supported_resolution);
if (bytes_recvd < need)
break;
if (msg->resolution_resp.resolution_count >
SYNTHVID_MAX_RESOLUTION_COUNT) {
drm_err_ratelimited(...);
return;
}
need += msg->resolution_resp.resolution_count *
sizeof(struct hvd_screen_info);
break;
```
First validates the fixed prefix (EDID block + count/index/is_standard = 131 bytes), then reads `resolution_count`, bounds it, and requires exactly the count-sized array. This avoids the v3 bug where requiring the full `sizeof(struct synthvid_supported_resolution_resp)` (= 387 bytes) would reject the shorter responses the host legitimately sends when fewer than 64 resolutions are reported.
**memcpy size change** — Critical improvement:
```c
// old: copies full 16 KiB regardless of actual data
memcpy(hv->init_buf, msg, VMBUS_MAX_PACKET_SIZE);
// new: copies only received data
memcpy(hv->init_buf, msg, bytes_recvd);
```
This eliminates the stale-data leak where `hyperv_get_supported_resolution()` and other consumers could read residual data from a prior message in `init_buf` beyond `bytes_recvd`. Combined with patch 1's bounds check on `resolution_count`, this closes the window where a short response combined with stale `init_buf` content could produce corrupt resolution data.
**`!ret` gating** — Essential with the new `memcpy(... bytes_recvd)`:
```c
if (!ret && bytes_recvd > 0 &&
recv_buf->pipe_hdr.type == PIPE_MSG_DATA)
hyperv_receive_sub(hdev, bytes_recvd);
```
On `vmbus_recvpacket()` returning `-ENOBUFS`, `bytes_recvd` contains the *required* buffer size, which can exceed `VMBUS_MAX_PACKET_SIZE`. Without the `!ret` gate, the old `VMBUS_MAX_PACKET_SIZE` memcpy was safe (both buffers are that size), but the new `bytes_recvd` memcpy would overflow both `recv_buf` and `init_buf`. The cover letter's analysis of this is accurate.
**Observation on completion timeout behavior:** When `hyperv_receive_sub()` rejects a packet (e.g., resolution count too large), it returns without calling `complete()`. The corresponding `wait_for_completion_timeout()` in `hyperv_get_supported_resolution()` / `hyperv_negotiate_version()` / `hyperv_update_vram_location()` will eventually time out and return `-ETIMEDOUT`. This is the correct degraded behavior — a corrupt response should not be treated as valid. Patch 1's fallback ensures the driver still gets usable WIN8 defaults.
**One subtlety worth noting:** The `need` variable is declared as `size_t` inside the `if` block, and `bytes_recvd` is `u32`. The comparison `bytes_recvd < need` promotes `bytes_recvd` to `size_t`, which is safe since `u32` → `size_t` is a widening conversion. No issue here.
Overall, this is a solid hardening series that follows good defensive coding patterns. Both patches are ready for merge.
---
Generated by Claude Code Patch Reviewer
next prev parent reply other threads:[~2026-05-25 9:37 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-21 20:41 [PATCH v4 0/2] drm/hyperv: harden host message parsing Berkant Koc
2026-05-19 20:08 ` [PATCH v4 1/2] drm/hyperv: validate resolution_count and fix WIN8 fallback Berkant Koc
2026-05-25 9:37 ` Claude review: " Claude Code Review Bot
2026-05-19 20:08 ` [PATCH v4 2/2] drm/hyperv: validate VMBus packet size in receive callback Berkant Koc
2026-05-22 21:09 ` Michael Kelley
2026-05-25 9:37 ` Claude Code Review Bot [this message]
2026-05-25 9:37 ` Claude review: drm/hyperv: harden host message parsing Claude Code Review Bot
-- strict thread matches above, loose matches on Subject: below --
2026-05-23 13:27 [PATCH v5 0/2] " Berkant Koc
2026-05-23 13:27 ` [PATCH v5 2/2] drm/hyperv: validate VMBus packet size in receive callback Berkant Koc
2026-05-25 7:45 ` Claude review: " Claude Code Review Bot
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=review-patch2-6e5d1d57a3afc4c5ea0d2a3d62be58c90741a869.1779396074.git.me@berkoc.com \
--to=claude-review@example.com \
--cc=dri-devel-reviews@example.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox