From patchwork Thu Feb 22 21:59:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vlastimil Babka X-Patchwork-Id: 13568180 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 55C5DC5478C for ; Thu, 22 Feb 2024 21:59:44 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id D89F26B007B; Thu, 22 Feb 2024 16:59:43 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id D3A586B007D; Thu, 22 Feb 2024 16:59:43 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id BDAF66B007E; Thu, 22 Feb 2024 16:59:43 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id AC7F36B007B for ; Thu, 22 Feb 2024 16:59:43 -0500 (EST) Received: from smtpin21.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 889F2A16D9 for ; Thu, 22 Feb 2024 21:59:43 +0000 (UTC) X-FDA: 81820807446.21.0FCB55F Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.223.130]) by imf08.hostedemail.com (Postfix) with ESMTP id 8696E160015 for ; Thu, 22 Feb 2024 21:59:41 +0000 (UTC) Authentication-Results: imf08.hostedemail.com; dkim=pass header.d=suse.cz header.s=susede2_rsa header.b=wv4Q32ts; dkim=pass header.d=suse.cz header.s=susede2_ed25519 header.b=fU9Ffb0G; dkim=pass header.d=suse.cz header.s=susede2_rsa header.b=wv4Q32ts; dkim=pass header.d=suse.cz header.s=susede2_ed25519 header.b=fU9Ffb0G; spf=pass (imf08.hostedemail.com: domain of vbabka@suse.cz designates 195.135.223.130 as permitted sender) smtp.mailfrom=vbabka@suse.cz; dmarc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1708639181; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:references:dkim-signature; bh=am0JE5DZxO41aBwalbrvXYDn2gxdsh5EjjlZFqMshpU=; b=75Cxp/PIdDeWk9k4QQBwVgzHPMxoOSOGR6Z8c3VvlQxYDw4IhDroxLsLY/svDdAUF2/DBv KYT07iVAOPpKoQLGGIIPKeuaYKCAA0u6dkiDK608diVmjbTmTDCxhLu2f4HgpfPTcHMqqz g6Z8Rp3ffK1q/Emoywmpj9Z4mTn4LQM= ARC-Authentication-Results: i=1; imf08.hostedemail.com; dkim=pass header.d=suse.cz header.s=susede2_rsa header.b=wv4Q32ts; dkim=pass header.d=suse.cz header.s=susede2_ed25519 header.b=fU9Ffb0G; dkim=pass header.d=suse.cz header.s=susede2_rsa header.b=wv4Q32ts; dkim=pass header.d=suse.cz header.s=susede2_ed25519 header.b=fU9Ffb0G; spf=pass (imf08.hostedemail.com: domain of vbabka@suse.cz designates 195.135.223.130 as permitted sender) smtp.mailfrom=vbabka@suse.cz; dmarc=none ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1708639181; a=rsa-sha256; cv=none; b=OP6tuJWfjMY8rljY14VwuXm3lQPZ6zXtSJCEiExy6ZLvAHWHvSOCGF3MXKBN+eI77e1ydL NLj2vt1rVYg6kyBWAg2wAFuF1p7X4wGASLx1PjrqHGJfZ8e2X7Rn1ZaHHyQ3i73wmGg11/ 24zXOhZcuzODDkZlXAnG0cmkmqm4Fjw= Received: from imap1.dmz-prg2.suse.org (imap1.dmz-prg2.suse.org [10.150.64.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 9B11A222A7; Thu, 22 Feb 2024 21:59:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1708639179; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=am0JE5DZxO41aBwalbrvXYDn2gxdsh5EjjlZFqMshpU=; b=wv4Q32tsmHh3ifubCsmDzZK4Z4l/6QoDAZYywCHKpFomrey0l1+JFyvCQo9HbfoK3TVIg5 n2tweB4nmtlXcgGNDpaL89xXaxFHfBNm8Sti4M+Nb3itDnujYBIA0w4Y9f2t/LRqaxjsqD JS/nqHPf9eogmVnkQBBWkDs9+AMO8Hc= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1708639179; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=am0JE5DZxO41aBwalbrvXYDn2gxdsh5EjjlZFqMshpU=; b=fU9Ffb0GdMF9xsMpPSxuvZm71lruVeVLYYUvCjEi3yj4wfcvgz6NEH5M0znRmL4pAlrwEI aldDoF+pBZygUeBA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1708639179; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=am0JE5DZxO41aBwalbrvXYDn2gxdsh5EjjlZFqMshpU=; b=wv4Q32tsmHh3ifubCsmDzZK4Z4l/6QoDAZYywCHKpFomrey0l1+JFyvCQo9HbfoK3TVIg5 n2tweB4nmtlXcgGNDpaL89xXaxFHfBNm8Sti4M+Nb3itDnujYBIA0w4Y9f2t/LRqaxjsqD JS/nqHPf9eogmVnkQBBWkDs9+AMO8Hc= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1708639179; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=am0JE5DZxO41aBwalbrvXYDn2gxdsh5EjjlZFqMshpU=; b=fU9Ffb0GdMF9xsMpPSxuvZm71lruVeVLYYUvCjEi3yj4wfcvgz6NEH5M0znRmL4pAlrwEI aldDoF+pBZygUeBA== Received: from imap1.dmz-prg2.suse.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id 7B9E613A57; Thu, 22 Feb 2024 21:59:39 +0000 (UTC) Received: from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167]) by imap1.dmz-prg2.suse.org with ESMTPSA id AUbYHcvD12VLMwAAD6G6ig (envelope-from ); Thu, 22 Feb 2024 21:59:39 +0000 From: Vlastimil Babka To: Andrew Morton Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Vlastimil Babka , Michal Hocko , "Liam R . Howlett" , Lorenzo Stoakes , stable@vger.kernel.org Subject: [PATCH v2] mm, mmap: fix vma_merge() case 7 with vma_ops->close Date: Thu, 22 Feb 2024 22:59:31 +0100 Message-ID: <20240222215930.14637-2-vbabka@suse.cz> X-Mailer: git-send-email 2.43.1 MIME-Version: 1.0 X-Rspamd-Queue-Id: 8696E160015 X-Rspam-User: X-Stat-Signature: o4gnzjfk11mn3d1zb7t3pueapswy9k7e X-Rspamd-Server: rspam01 X-HE-Tag: 1708639181-156036 X-HE-Meta: U2FsdGVkX19frrD91dEmMFhx6Ke1NN/tnTNL0SnJP8TBa0imBBOvGS2LMsBvniJuMQHng57RFefPKNkt2S+/z7PnYd/0nD8BsYpRuPZAprXToBXIahDEY9nN6yp+A7ZXYK9oy24sU14oAXi1Kgj7yu1gcEhpFdo68McFs2HkVbUzaLzqCd1xDN3OfuYCA7UbHGHAERSflSgLIyXbb5HUXHDyaq/Q1V+V+3NtP2MclliNM0KypREijI9p88FdSI8tL8UjQIPAOA823ZgACv7PNQ6qckLFvopv09NfhVRtliR+B3MILhZYnnxnJ2RCy1FaR6sShzf+5A1qHY1D721WRAKlcdA7z+ZimD/gtnIHv3YJAMIvsPKBm1PqwCmycFqkqbP6tBLA0H53dKF3BBXtXCMPFPLCgo2vAl/JRtFmNcRUiMQEIn3u7bP08iFdm0j/BBhBm6SEseoISLWMNIp7JYh8LoIRCJ3+BbaOdCXyBCCI9M2yrysonPcF6g+R3TQOcuS0ZCQpCxTyN3oAguD0nTeaKclahXsmR6YkymRQV5T/iKR7YCtJfv9GpCEk3pHLBgQrlWIm3pE4QSZYdplqQouG1cdSiZy+q3jqxM4W1I/nMHzbqNmTWESajqtPhBlngprBISdDfGb9A0I1lKOVQ0SvBEczSe7lQjJ34BfQiczG7OU2VKUieJNQEIcyb24L2HDObfSzIEg7k3jFm3dhEVU06hFrl31TvEJzmu705QBtuutcULMHILCsceWqI4kbuHXhW780ssYDguu0JVehs6pUrKyqjY1K2IOCdri9FDhesLDTYqUJm1emy/LB7iTCDrN8MIxkntf+g7TlM1C6kbMSzNTkYLthx4cEOr8T/FGFO8UgJKcMhnPPFar7P66bE5JmZajzkpOGPlwirB4zT4f785eB+gM6BwXXo7sPxJq0MvEdqIUpI9pjOQm0jdpb2SSC432lrW32khFvYcx P8Uk5ZuU vHSbH724PlJqkUVg= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: When debugging issues with a workload using SysV shmem, Michal Hocko has come up with a reproducer that shows how a series of mprotect() operations can result in an elevated shm_nattch and thus leak of the resource. The problem is caused by wrong assumptions in vma_merge() commit 714965ca8252 ("mm/mmap: start distinguishing if vma can be removed in mergeability test"). The shmem vmas have a vma_ops->close callback that decrements shm_nattch, and we remove the vma without calling it. vma_merge() has thus historically avoided merging vma's with vma_ops->close and commit 714965ca8252 was supposed to keep it that way. It relaxed the checks for vma_ops->close in can_vma_merge_after() assuming that it is never called on a vma that would be a candidate for removal. However, the vma_merge() code does also use the result of this check in the decision to remove a different vma in the merge case 7. A robust solution would be to refactor vma_merge() code in a way that the vma_ops->close check is only done for vma's that are actually going to be removed, and not as part of the preliminary checks. That would both solve the existing bug, and also allow additional merges that the checks currently prevent unnecessarily in some cases. However to fix the existing bug first with a minimized risk, and for easier stable backports, this patch only adds a vma_ops->close check to the buggy case 7 specifically. All other cases of vma removal are covered by the can_vma_merge_before() check that includes the test for vma_ops->close. The reproducer code, adapted from Michal Hocko's code: int main(int argc, char *argv[]) { int segment_id; size_t segment_size = 20 * PAGE_SIZE; char * sh_mem; struct shmid_ds shmid_ds; key_t key = 0x1234; segment_id = shmget(key, segment_size, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR); sh_mem = (char *)shmat(segment_id, NULL, 0); mprotect(sh_mem + 2*PAGE_SIZE, PAGE_SIZE, PROT_NONE); mprotect(sh_mem + PAGE_SIZE, PAGE_SIZE, PROT_WRITE); mprotect(sh_mem + 2*PAGE_SIZE, PAGE_SIZE, PROT_WRITE); shmdt(sh_mem); shmctl(segment_id, IPC_STAT, &shmid_ds); printf("nattch after shmdt(): %lu (expected: 0)\n", shmid_ds.shm_nattch); if (shmctl(segment_id, IPC_RMID, 0)) printf("IPCRM failed %d\n", errno); return (shmid_ds.shm_nattch) ? 1 : 0; } Fixes: 714965ca8252 ("mm/mmap: start distinguishing if vma can be removed in mergeability test") Signed-off-by: Vlastimil Babka Reported-by: Michal Hocko Cc: Liam R. Howlett Cc: Lorenzo Stoakes Cc: Reviewed-by: Lorenzo Stoakes Reviewed-by: Liam R. Howlett --- v2: deduplicate code, per Lorenzo mm/mmap.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/mm/mmap.c b/mm/mmap.c index d89770eaab6b..3281287771c9 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -954,13 +954,21 @@ static struct vm_area_struct } else if (merge_prev) { /* case 2 */ if (curr) { vma_start_write(curr); - err = dup_anon_vma(prev, curr, &anon_dup); if (end == curr->vm_end) { /* case 7 */ + /* + * can_vma_merge_after() assumed we would not be + * removing prev vma, so it skipped the check + * for vm_ops->close, but we are removing curr + */ + if (curr->vm_ops && curr->vm_ops->close) + err = -EINVAL; remove = curr; } else { /* case 5 */ adjust = curr; adj_start = (end - curr->vm_start); } + if (!err) + err = dup_anon_vma(prev, curr, &anon_dup); } } else { /* merge_next */ vma_start_write(next);