From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-qk1-f179.google.com (mail-qk1-f179.google.com [209.85.222.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 38F9C2BEC34 for ; Fri, 10 Jul 2026 02:29:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.179 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783650563; cv=none; b=mydIurdwn1LMIl9LttU6yaI5O3U0p5pBZt1HHYrRrJG77ByXSgfBfsMWr8bddP2i46c3LDgFC7wc/rSuLuh25BsH4nYCQnE1QDdBXbx8vUiI1V5/MeV9Coozf/xnSjUozexzUoWcywrJLKVmgqT9NJ96jig79WIxNonfC7wGLvU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783650563; c=relaxed/simple; bh=wsHM+8ZeYOqCJwA/6tpF0q5nafYPW3zlwHQ3/xAjE6E=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=W1dHKRjuh3PblLhk1oPipW+r3nkwcqlHxlLeU/bMcBy5wUw/Hz2VXqi0LFzC37lPe2kEIcRyfDBhIC0N65oPZqYqI54scPOwp/LXTwTgAQqTBY8jmaqyJl619SMGjZOCoIUn5L/VxsIBlhr/HkegTfZY+xAieYChL02bAyDnGtU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=PqTrvVUn; arc=none smtp.client-ip=209.85.222.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="PqTrvVUn" Received: by mail-qk1-f179.google.com with SMTP id af79cd13be357-9204711e831so34108985a.2 for ; Thu, 09 Jul 2026 19:29:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783650561; x=1784255361; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=+VrbOIz5DjpeTHI1zJiQK8GMybM0cRVGEIt9+g4I/iE=; b=PqTrvVUnaBupsH9/QjAjP4yHzhxlVYCizcAWeVJiLKUwDa+QaHD0BZEI2Qj2Nv4yGT I13FnCkxM62jIQjX/afy9CVWI/6DfGcKmTTkFRGl3G31QaJiJPEbDnqSvZCRpEeq0sdc w32G2e+JKcK23ix6mszoA3P2TVXp/SmtOjMjW6nJqJvXz1aQVOQ4IrrA5WtUw+sGESnA gpbVTI6HSQ+/wT0iyl3SFl6CQG4ssvyepaZM9VLy2xwpdUkEKhnDl0fghcRQ7KYn1hNu pdC3RxvdM+6xk8xK0QYvp769oFrUfQvHE4YfNtNNyZYzukoomhZFnMTwQqt8SqjjpU4L Fb8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783650561; x=1784255361; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=+VrbOIz5DjpeTHI1zJiQK8GMybM0cRVGEIt9+g4I/iE=; b=sdlo1lgYDjFSOpVb5wNmdTlau1tT6JFSzFUI/dEWQxU7jpjjW8LfBYpM7DuF19m6lL sOWgzQ+t1kK6hS0R6kiJKAxRW2RJqvQV3yzL+jVP8EzTGybszuxmOb8DY8QJHxdw0ZA0 KbJS/9nLN0w1/+708+Ds0AfJKlU4vg4LRuqWG5tTJveiTE5C0jxy9Qzf0JbYVXXQ8K3e Rbz6EVYpxMEt6Um3XBt/tmHRGhpFi1bQD87JOdnjVJceT/5l1CfrWFXkOgHzC1Sl4lnh Fuk7xMShAkgUkyguABSyKftNNzbWV/kdIxCuygZqo7uGD9ZSgV4k6a8OskfKrcgH5/SO HKdw== X-Forwarded-Encrypted: i=1; AHgh+Row99XmM4FoudEG5W0Sa/39rWbL1p8lqCvk4dOn85qYwCOM9kkbXDMNGY+UraZchzpLiA5tG/f+sSZeKWs=@vger.kernel.org X-Gm-Message-State: AOJu0YwtFiJPLkCVipMLsfcFEoVMHTJEmcx3tgwwqKGhLZLpZVzWENrF 6vks4mPKq5XPkbUgSxZiMRiJ4A/PXl6XuI2zgkL6+MwUVtjPb6fWJtDD X-Gm-Gg: AfdE7cmV76HTzyA8rxsUlPlD5UegEQl8/+lQzOamDXuRCgf9WGk2UqIC6VL/RtwUGou VXG/vwofyQFahOKzy95snM0qbqmdntfz2nJ73tscAKzHd8q+EqllEBo0eMtm4DnhNQI192XdOKC PvAOvP6t2AI2a/AxJfPylUX6RUQu6X7iJQ6p0HHbkfxEsmqFKC26lBOH5Nn0Slvh9bEwVwDCoRZ 5L+faQpntYYypSxo9UZAawNwYqZIiq+b5jWrojkWc6Ujh7IE/terhPUwBzDfgz9w6mm/ekd1RX7 cWncyPD2Q5KK2W9AwnHnVXGtvfdQ6FF8Bqih0qHj0uk3HH2ww8lOvEXZAtiI9hm1opJo4DVhdTy c8mI3TAmfUgYvqwBH0IRqCr+CZ5cHlzoxSUNJbKFwzEo0OOaIeInOvkzys0O2stUYYdca+eNfdg 1WYKq+4v5ppt5JycJQuCsUUjGZ0KjUJFkEjaLIYGCgn131dIoYV+YJgw7B069Mg8YQfsKpMeRUG hFJl2bL/XkBHzbEo8qh/h/Q2Wej4Oqf X-Received: by 2002:a05:620a:170e:b0:92e:5a74:962e with SMTP id af79cd13be357-92ecf8f520bmr1013173385a.62.1783650560868; Thu, 09 Jul 2026 19:29:20 -0700 (PDT) Received: from server0.tail6e7dd.ts.net (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-92ee5d61fb9sm86411685a.41.2026.07.09.19.29.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2026 19:29:20 -0700 (PDT) From: Michael Bommarito To: kys@microsoft.com, Haiyang Zhang , Wei Liu , Dexuan Cui , Long Li Cc: Greg Kroah-Hartman , linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH] hv: hv_balloon: validate unballoon range count Date: Thu, 9 Jul 2026 22:29:14 -0400 Message-ID: <20260710022914.3740453-1-michael.bommarito@gmail.com> X-Mailer: git-send-email 2.53.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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. 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: stable@vger.kernel.org Assisted-by: Codex:gpt-5-5-xhigh Signed-off-by: Michael Bommarito --- 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