From patchwork Tue Jul 25 13:45:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tokarev X-Patchwork-Id: 1812548 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R9JHv02G0z1ydq for ; Tue, 25 Jul 2023 23:47:39 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qOINY-0007EA-01; Tue, 25 Jul 2023 09:47:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qOINK-000610-Ds; Tue, 25 Jul 2023 09:46:56 -0400 Received: from isrv.corpit.ru ([86.62.121.231]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qOINH-0001bD-PB; Tue, 25 Jul 2023 09:46:54 -0400 Received: from tsrv.corpit.ru (tsrv.tls.msk.ru [192.168.177.2]) by isrv.corpit.ru (Postfix) with ESMTP id 509D0160FC; Tue, 25 Jul 2023 16:45:36 +0300 (MSK) Received: from tls.msk.ru (mjt.wg.tls.msk.ru [192.168.177.130]) by tsrv.corpit.ru (Postfix) with SMTP id DCA68194BF; Tue, 25 Jul 2023 16:45:33 +0300 (MSK) Received: (nullmailer pid 3370843 invoked by uid 1000); Tue, 25 Jul 2023 13:45:29 -0000 From: Michael Tokarev To: qemu-devel@nongnu.org Cc: qemu-stable@nongnu.org, Helge Deller , "Markus F.X.J. Oberhumer" , Michael Tokarev Subject: [Stable-8.0.4 20/31] linux-user: Prohibit brk() to to shrink below initial heap address Date: Tue, 25 Jul 2023 16:45:05 +0300 Message-Id: <20230725134517.3370706-20-mjt@tls.msk.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=86.62.121.231; envelope-from=mjt@tls.msk.ru; helo=isrv.corpit.ru X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Helge Deller Since commit 86f04735ac ("linux-user: Fix brk() to release pages") it's possible for userspace applications to reduce their memory footprint by calling brk() with a lower address and free up memory. Before that commit guest heap memory was never unmapped. But the Linux kernel prohibits to reduce brk() below the initial memory address which is set at startup by the set_brk() function in binfmt_elf.c. Such a range check was missed in commit 86f04735ac. This patch adds the missing check by storing the initial brk value in initial_target_brk and verify any new brk addresses against that value. Tested with the i386 upx binary from https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-i386_linux.tar.xz Signed-off-by: Helge Deller Tested-by: "Markus F.X.J. Oberhumer" Fixes: 86f04735ac ("linux-user: Fix brk() to release pages") Cc: qemu-stable@nongnu.org Buglink: https://github.com/upx/upx/issues/683 (cherry picked from commit dfe49864afb06e7e452a4366051697bc4fcfc1a5) Signed-off-by: Michael Tokarev diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 450487af57..e106633837 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -801,12 +801,13 @@ static inline int host_to_target_sock_type(int host_type) return target_type; } -static abi_ulong target_brk; +static abi_ulong target_brk, initial_target_brk; static abi_ulong brk_page; void target_set_brk(abi_ulong new_brk) { target_brk = TARGET_PAGE_ALIGN(new_brk); + initial_target_brk = target_brk; brk_page = HOST_PAGE_ALIGN(target_brk); } @@ -824,6 +825,11 @@ abi_long do_brk(abi_ulong brk_val) return target_brk; } + /* do not allow to shrink below initial brk value */ + if (brk_val < initial_target_brk) { + brk_val = initial_target_brk; + } + new_brk = TARGET_PAGE_ALIGN(brk_val); new_host_brk_page = HOST_PAGE_ALIGN(brk_val);