From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-01.1984.is (mail-01.1984.is [185.112.145.69]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C67A23B4EA5; Sun, 17 May 2026 14:16:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.112.145.69 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779027386; cv=none; b=cNZyz+rvybQV3JrLlQu0ycGcNkT8G9ZabGYRndeIR7FgxWb2aHdqwsNh21XPZGWPfEokaDNOvEn9GMxQR8rQl4mAyUTuafUhDUoZ727M7kCpvUza4DW+MXQea4gGsOhzz+d+uIs3940xM+JOHSqZ9NpGv8Ap/61LKgh5xkxfKes= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779027386; c=relaxed/simple; bh=wfRtwd5UyLQeg6FmTxzzEcj0AG+dbYmOt73exLQ4iWo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=fIMzutSPGsz9pMkjNrXRxbfH9GBEghC5VXb+baK6atX3m+DgPvUFu1tJuZGw6heBVA5h/HcVailJJtigiVYLULjadyhSDcUtquvyGQLAuuyTdXRVkm2FPhSUVz9Ww4KfAi1H8NQKh76bUfBbNdHZP7zZluxSzPby8Bvrni6I//o= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=berkoc.com; spf=pass smtp.mailfrom=berkoc.com; dkim=pass (2048-bit key) header.d=berkoc.com header.i=@berkoc.com header.b=JQs7UWV+; arc=none smtp.client-ip=185.112.145.69 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=berkoc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=berkoc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=berkoc.com header.i=@berkoc.com header.b="JQs7UWV+" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=berkoc.com; s=1984; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=MQ8YiYdNWpRqmjF8/PofO4sgGjF2gJ1u/rtwQhqBB4A=; b=JQs7UWV+0f8ACDzMvMmCgR0P+M RTTcR2fvyyLiN35YD/qnMLGg+S22ZsPGZOZgqz/olECemqjiiGdWEUc4PCuToI8QTEOd3LSaq8bzz OHHhyTlaJo/a0tJHLhvikNDv7lDbfOiqzd6Ro1+Q2rFGytyES7TMECdTFh4vRyieuAC1Y6JsvhtEs enBLO3JpZZUlhhRgkpPKAZ1fl7cUboQELh8+wNn5KT/Ff9GF5p5TpLuK5ecz6xojdLxkP12heZpYh HG1q8c6ejzhm2qkdICdc9kSIwxEgeul/CrJoyHx/csIiUoJ6EqCdj08clvJJO2qy4JWrVwOuUzaI1 EOvzZ8qA==; Received: from localhost by mail-01.1984.is with utf8esmtp (Exim 4.96) (envelope-from ) id 1wOcHk-00GB2e-1S; Sun, 17 May 2026 14:16:05 +0000 From: Berkant Koc To: Saurabh Sengar , Dexuan Cui , Long Li Cc: linux-hyperv@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, "K. Y. Srinivasan" , Haiyang Zhang , Wei Liu , Michael Kelley , Thomas Zimmermann , Maarten Lankhorst , Maxime Ripard , Deepak Rawat , stable@vger.kernel.org Subject: [PATCH v2 2/2] drm/hyperv: validate VMBus packet size in receive callback Date: Sun, 17 May 2026 16:25:02 +0200 Message-ID: <20260517-drm-hyperv-patch2-v2@berkoc.com> In-Reply-To: <20260517-drm-hyperv-cover-v2@berkoc.com> References: <20260517-drm-hyperv-cover@berkoc.com> <20260517-drm-hyperv-patch2@berkoc.com> <20260517-drm-hyperv-cover-v2@berkoc.com> Precedence: bulk X-Mailing-List: linux-hyperv@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit User-Agent: git-send-email/2.47.3 X-Spam-Score: -0.0 (/) X-Authenticated-User: me@berkoc.com X-Sender-Address: me@berkoc.com hyperv_receive() reads bytes_recvd from vmbus_recvpacket() but does not forward that value to hyperv_receive_sub(). The sub-handler reads msg->vid_hdr.type and msg->feature_chg.is_dirt_needed without knowing how many bytes the host actually wrote, so a short packet leaves the parser reading bytes that the host did not write in this packet. The unconditional memcpy(hv->init_buf, msg, VMBUS_MAX_PACKET_SIZE) on the wait-completion path also copies the full 16 KiB recv_buf regardless of bytes_recvd, including any residue from the prior message. Pass bytes_recvd into hyperv_receive_sub() and reject any packet shorter than the pipe + synthvid header. The dirt-feature branch additionally requires the feature_change payload size before reading is_dirt_needed. The init_buf copy now uses bytes_recvd as the length argument, which keeps it bounded by VMBUS_MAX_PACKET_SIZE through the new upper check. Unchanged from v1. Fixes: 76c56a5affeb ("drm/hyperv: Add DRM driver for hyperv synthetic video device") Cc: stable@vger.kernel.org # 5.14+ Signed-off-by: Berkant Koc --- drivers/gpu/drm/hyperv/hyperv_drm_proto.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_proto.c b/drivers/gpu/drm/hyperv/hyperv_drm_proto.c index 3b5065fe06e4..cdab4895dd40 100644 --- a/drivers/gpu/drm/hyperv/hyperv_drm_proto.c +++ b/drivers/gpu/drm/hyperv/hyperv_drm_proto.c @@ -423,26 +423,35 @@ static int hyperv_get_supported_resolution(struct hv_device *hdev) return 0; } -static void hyperv_receive_sub(struct hv_device *hdev) +static void hyperv_receive_sub(struct hv_device *hdev, u32 bytes_recvd) { struct hyperv_drm_device *hv = hv_get_drvdata(hdev); struct synthvid_msg *msg; + size_t hdr_size; if (!hv) return; + hdr_size = sizeof(struct pipe_msg_hdr) + + sizeof(struct synthvid_msg_hdr); + if (bytes_recvd < hdr_size || bytes_recvd > VMBUS_MAX_PACKET_SIZE) + return; + msg = (struct synthvid_msg *)hv->recv_buf; /* Complete the wait event */ if (msg->vid_hdr.type == SYNTHVID_VERSION_RESPONSE || msg->vid_hdr.type == SYNTHVID_RESOLUTION_RESPONSE || msg->vid_hdr.type == SYNTHVID_VRAM_LOCATION_ACK) { - memcpy(hv->init_buf, msg, VMBUS_MAX_PACKET_SIZE); + memcpy(hv->init_buf, msg, bytes_recvd); complete(&hv->wait); return; } if (msg->vid_hdr.type == SYNTHVID_FEATURE_CHANGE) { + if (bytes_recvd < hdr_size + + sizeof(struct synthvid_feature_change)) + return; hv->dirt_needed = msg->feature_chg.is_dirt_needed; if (hv->dirt_needed) hyperv_hide_hw_ptr(hv->hdev); @@ -469,7 +478,7 @@ static void hyperv_receive(void *ctx) &bytes_recvd, &req_id); if (bytes_recvd > 0 && recv_buf->pipe_hdr.type == PIPE_MSG_DATA) - hyperv_receive_sub(hdev); + hyperv_receive_sub(hdev, bytes_recvd); } while (bytes_recvd > 0 && ret == 0); } -- 2.47.3