From patchwork Wed Nov 20 10:23:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alessandro Carminati X-Patchwork-Id: 13880980 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 22B31D63922 for ; Wed, 20 Nov 2024 10:24:39 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 9DCBD6B007B; Wed, 20 Nov 2024 05:24:38 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 98C696B0083; Wed, 20 Nov 2024 05:24:38 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 8546D6B0085; Wed, 20 Nov 2024 05:24:38 -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 667D16B007B for ; Wed, 20 Nov 2024 05:24:38 -0500 (EST) Received: from smtpin28.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id 20D4C1607CA for ; Wed, 20 Nov 2024 10:24:38 +0000 (UTC) X-FDA: 82806088932.28.29D5A13 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by imf14.hostedemail.com (Postfix) with ESMTP id D4EA0100002 for ; Wed, 20 Nov 2024 10:23:38 +0000 (UTC) Authentication-Results: imf14.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=ciZkus1t; spf=pass (imf14.hostedemail.com: domain of acarmina@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=acarmina@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1732098126; 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-type: content-transfer-encoding:content-transfer-encoding:in-reply-to: references:dkim-signature; bh=p/iBJks2mitS8xx8UW4h8YzqskEGlCYT8cc+MxErLho=; b=TojhnsXOBXim3m7znHAwFruQM//XLPQPVoeE+NIkrJaZHfCdrGiWMQvs5BVp4mi7WNEECU Pq7VGPqk2NWmvrlf7i+MEvHJALmDh39PSa+AJ2qs3h5gHgifdH1Oy+SRay4um0Z0wcqnu8 PRdb8yJPXKKFzQUibHLfyRrRAgfQwAw= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1732098126; a=rsa-sha256; cv=none; b=HKOADcx9XlbJtPBN1cQAW7A/YET6u6X+/DGVyXb2iVwi5x/2PZxS8bVcictlGldZD0mp+v 0r+hp3s2pdi7RmMwUBzZBOWbZ3uQ9reDbdUwSTJgNsMHsiDgjfOvZJt24j+IawYwB5vb6O +bKs2lU8l7MVGIeLO1ogS7lj63FcUao= ARC-Authentication-Results: i=1; imf14.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=ciZkus1t; spf=pass (imf14.hostedemail.com: domain of acarmina@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=acarmina@redhat.com; dmarc=pass (policy=none) header.from=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1732098275; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=p/iBJks2mitS8xx8UW4h8YzqskEGlCYT8cc+MxErLho=; b=ciZkus1tp77NxWmfhe/kOfAMJwHsmdDSnmqJaEibhohwzu4ST6w1h168RzqH0oOM6gxWjM beQPtaTHZ7dzhQTDaxMtsQY3Jcr+I1P83wz4DmWS1oSRUnVBRxUybqHxvIUZCVn8/qvkkP u0U5qbSs7Tt/a8zIF8pIBvYD4cmTQ9k= Received: from mail-ed1-f72.google.com (mail-ed1-f72.google.com [209.85.208.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-462-ysUEyFDbN1mpqNa2KC1u-g-1; Wed, 20 Nov 2024 05:24:34 -0500 X-MC-Unique: ysUEyFDbN1mpqNa2KC1u-g-1 X-Mimecast-MFC-AGG-ID: ysUEyFDbN1mpqNa2KC1u-g Received: by mail-ed1-f72.google.com with SMTP id 4fb4d7f45d1cf-5cfca544b47so2372724a12.0 for ; Wed, 20 Nov 2024 02:24:33 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732098272; x=1732703072; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=p/iBJks2mitS8xx8UW4h8YzqskEGlCYT8cc+MxErLho=; b=WatDKqHBPhO+3q6TlfhccvQ6rzP8x4skw3a+1aEcLV62I3BLX+SuYVPTvLwYnV75Uw /DZwC1UuGgNFxBqKRlSPttBTJFR4X0NKpvVrerYE5rtiDz46psi2myizV6Rpl0/7QxDR ZCiHSQFmw+mqvudhX+CmSCFEmXxW8paV6FshyHnKToKpkr73zMjJ6FbgFHH6xImH6PQa b4x1tPD/eUTii4ICekATHOvRGeKfGhe8O2l6jCbnX5I6mVo3nv7q6UrZHgRTy/qKCtsR aUtbKqLNB/Aie/bMvSdqDJcUOOwYpHrUzrNf5IWl2YBUnn7ZLAXCb/81aXLTI41F7cgv +OCg== X-Forwarded-Encrypted: i=1; AJvYcCU7tHMuYo15GfoZpvNBraiX2UNG4E37qlPTC7zf/7PnRTzn/bJr1jb+Tp5tjc3X85flq9eHLoKdmQ==@kvack.org X-Gm-Message-State: AOJu0YyBFyOMgn707IULwtEXn68fLmHi/ZtGrooX0iRLpH3sTs6Zhw1s 8oyJcBAWWWGQkrpSUcuklSl5LfGLfnByhBlunLMo3ZldDnVziw+Y54+TT3R8rHvyGdfwPsoPdI9 rxVMRr/cSpdsoS1xN7qyfI0tAqintjfVDDU6Jg69OJ0+IEEPqPfuWZngIM6g= X-Received: by 2002:a05:6402:430b:b0:5cf:e022:24f5 with SMTP id 4fb4d7f45d1cf-5cff4afd5b8mr1390775a12.2.1732098272489; Wed, 20 Nov 2024 02:24:32 -0800 (PST) X-Google-Smtp-Source: AGHT+IHYa8gJ77UzAO3+WSjRuopMOyzPLYeoXq2QJfC/hbjhkfVpAmRLCa3elDekTiUsEaip20iS2Q== X-Received: by 2002:a05:6402:430b:b0:5cf:e022:24f5 with SMTP id 4fb4d7f45d1cf-5cff4afd5b8mr1390752a12.2.1732098272037; Wed, 20 Nov 2024 02:24:32 -0800 (PST) Received: from lab.hqhome163.com ([194.183.10.152]) by smtp.googlemail.com with ESMTPSA id 4fb4d7f45d1cf-5cff44efb03sm653932a12.29.2024.11.20.02.24.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Nov 2024 02:24:31 -0800 (PST) From: Alessandro Carminati To: Catalin Marinas , Andrew Morton , Sebastian Andrzej Siewior , Clark Williams , Steven Rostedt , linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-rt-devel@lists.linux.dev, Thomas Weissschuh Cc: Alessandro Carminati , Juri Lelli , Gabriele Paoloni , Eric Chanudet , Alessandro Carminati Subject: [PATCH] mm/kmemleak: Fix sleeping function called from invalid context in kmemleak_seq_show Date: Wed, 20 Nov 2024 10:23:25 +0000 Message-Id: <20241120102325.3538-1-acarmina@redhat.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: ZNRafG9Fj2mmeyzHIQTt6l5IjtOy0a5sGT3HRbnVudE_1732098273 X-Mimecast-Originator: redhat.com Content-type: text/plain X-Rspam-User: X-Rspamd-Server: rspam12 X-Rspamd-Queue-Id: D4EA0100002 X-Stat-Signature: ncrsyw7jh8168tyfku3nzmrstmjq98w9 X-HE-Tag: 1732098218-848349 X-HE-Meta: U2FsdGVkX186BZD4tu4SL7M+qIlVLa6cuElyTB2KxoNNh6476YaJUDNFoYuKKwEvPlSQylmPmKFDqfN9D+J/xZHqiNVWb1aVVgrQJt1lvRRmAjCsseP6qjS89z9zZ6YhyK4AbvBkdhD6I7K6+fGGzVOMUorgGa/FWolAWcbX+fB5C3/tBZf5rdtayZr/bdBUve8TB+b3YfcqklpEoMU+cvyCh82CkQKAeRzQwFQIe5pqfzg0kmfaJQ+ACZETHUfVJNrfflWaDtRb4/viFuDbsdo+H4MimAiksGjdcyHJ5hsqanrCR0X9YKSjuyGrzFyoqI/My3SyYif2XSHVjyAGdpeDJkOOlZ4wWSHBOcde/5nKLS7/dcL24QdZv/nta+veHMokWgqAGNJq8L7ugzoB6s5OKX2mnpggRwNKtejmavIJcRGaIKZ30XNPynHai6nsmP9I70th9+Jp5iesJWwFvpGk53Lx8xQ+tSSe6+QERF6l7A79do+GERxCcgTckWv2drfMv1BWHfbFnzIZFp3inGi5y9LjvFduw0FnzPTJgyS2Db/4uJCVxi1exJNJfA2eO+lHQIUaHYthzyLha7Pzhp0Op8BYO7N9MS/dXtvOD51WLMJyIs7LvoGMWkpgcBFt1J+xvIyQE/Dog/MOhWQGChehQ/zF3TLIGsCgE+UiEJhDUAjlMCR7+bWgcmrYXM9HKnjBzNfOQulDhuon6jngc6yEQqTJO/JPUNdI5MFGkOc7pORtE/0pyXcYnrpD+VnB4k2bdqd7Lu4MHlWrX8bqZGzOuad0u6Y0Frcic8bcTpgLhWxcqEwD5RAxHGOhn99Lr/tli3zjpYCG4iLo9REIvJO04D8x6k+2jLLlXSu2mTr1sxwMxbyFxN9nQ//+8C26Ndqxb7hwpSDKyg+rOb9QAAH4J6Ss3M1QOwYB178+TtBf+s5uJ14X8eF7aCpLxNoTwLLMlKv7lwIVBUVUYlM AW+HxjX6 mnUZzERhmWIURdOYb05VmI8kAyzrbcuRb4oYaSpR9vDDQhzbSFtdR13VtsaRUhhfh6Gu6zpv7sRMeIqPZGM/vUvEVq2DLo60OxFczGR6Fwc8UGQ/eyjahGt3Wc4XVz46GGCmECp8kRVn9Zkzv8DzW/lbpw2+sxtSEEGdsy26d5uWKLaQYHYW5MuRMBjRFL8rfkEEm0HVzPTYvPM3gClqjxO3Wj1QWZv76+us9nkyTD4jA/kIP7QFiCB+qyY3hHQlm3Jc5phjT0ZnKbE9+l/4jtA4QlO+zzILJRACvDBrkrD6oHi8OR9n2vrcIAOSls+FaZx0e7hEnMYFCXXUBwusIrPodL3hKpQLpC7mAShUqSz3UvMrvQq+Spmk71Hflveb5WTg6aOirJ0Cq/9zXEZEy+fyVbQNIPtOA2WU620PtX4mV7t4tijywZBoxwahnlMagr5kS1ObX6a8+uZaGWh9Y3gqnhyx1h3H/9pHMdrBrC7D+u7qKtsdhttgMpA== 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: This patch addresses a bug in the RT variant of the kernel where a "sleeping function called from invalid context" warning may occur in kmemleak_seq_show under specific conditions: - CONFIG_PREEMPT_RT=y - SELinux is the LSM for the system - `kptr_restrict` is set to 1. - The kmemleak buffer contains at least one item. Commit 8c96f1bc6fc49c724c4cdd22d3e99260263b7384 ("mm/kmemleak: turn kmemleak_lock and object->lock to raw_spinlock_t") introduced a change where kmemleak_seq_show is executed in atomic context within the RT kernel. However, the SELinux capability check within this function flow still relies on regular spinlocks, leading to potential race conditions that trigger the error when printing the kmemleak backtrace. To resolve this, the backtrace printing has been moved out of the critical section. Signed-off-by: Alessandro Carminati --- Please read previous conversation in the RFC https://lore.kernel.org/all/20241115145410.114376-1-acarmina@redhat.com/ Splash triggering this patch: ``` [ 159.247069] BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48 [ 159.247193] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 136, name: cat [ 159.247241] preempt_count: 1, expected: 0 [ 159.247277] RCU nest depth: 2, expected: 2 [ 159.247388] 6 locks held by cat/136: [ 159.247438] #0: ffff32e64bcbf950 (&p->lock){+.+.}-{3:3}, at: seq_read_iter+0xb8/0xe30 [ 159.248835] #1: ffffafe6aaa9dea0 (scan_mutex){+.+.}-{3:3}, at: kmemleak_seq_start+0x34/0x128 [ 159.249053] #3: ffff32e6546b1cd0 (&object->lock){....}-{2:2}, at: kmemleak_seq_show+0x3c/0x1e0 [ 159.249127] #4: ffffafe6aa8d8560 (rcu_read_lock){....}-{1:2}, at: has_ns_capability_noaudit+0x8/0x1b0 [ 159.249205] #5: ffffafe6aabbc0f8 (notif_lock){+.+.}-{2:2}, at: avc_compute_av+0xc4/0x3d0 [ 159.249364] irq event stamp: 136660 [ 159.249407] hardirqs last enabled at (136659): [] _raw_spin_unlock_irqrestore+0xa8/0xd8 [ 159.249465] hardirqs last disabled at (136660): [] _raw_spin_lock_irqsave+0x8c/0xb0 [ 159.249518] softirqs last enabled at (0): [] copy_process+0x11d8/0x3df8 [ 159.249571] softirqs last disabled at (0): [<0000000000000000>] 0x0 [ 159.249970] Preemption disabled at: [ 159.249988] [] kmemleak_seq_show+0x3c/0x1e0 [ 159.250609] CPU: 1 UID: 0 PID: 136 Comm: cat Tainted: G E 6.11.0-rt7+ #34 [ 159.250797] Tainted: [E]=UNSIGNED_MODULE [ 159.250822] Hardware name: linux,dummy-virt (DT) [ 159.251050] Call trace: [ 159.251079] dump_backtrace+0xa0/0x128 [ 159.251132] show_stack+0x1c/0x30 [ 159.251156] dump_stack_lvl+0xe8/0x198 [ 159.251180] dump_stack+0x18/0x20 [ 159.251227] rt_spin_lock+0x8c/0x1a8 [ 159.251273] avc_perm_nonode+0xa0/0x150 [ 159.251316] cred_has_capability.isra.0+0x118/0x218 [ 159.251340] selinux_capable+0x50/0x80 [ 159.251363] security_capable+0x7c/0xd0 [ 159.251388] has_ns_capability_noaudit+0x94/0x1b0 [ 159.251412] has_capability_noaudit+0x20/0x30 [ 159.251437] restricted_pointer+0x21c/0x4b0 [ 159.251461] pointer+0x298/0x760 [ 159.251482] vsnprintf+0x330/0xf70 [ 159.251504] seq_printf+0x178/0x218 [ 159.251526] print_unreferenced+0x1a4/0x2d0 [ 159.251551] kmemleak_seq_show+0xd0/0x1e0 [ 159.251576] seq_read_iter+0x354/0xe30 [ 159.251599] seq_read+0x250/0x378 [ 159.251622] full_proxy_read+0xd8/0x148 [ 159.251649] vfs_read+0x190/0x918 [ 159.251672] ksys_read+0xf0/0x1e0 [ 159.251693] __arm64_sys_read+0x70/0xa8 [ 159.251716] invoke_syscall.constprop.0+0xd4/0x1d8 [ 159.251767] el0_svc+0x50/0x158 [ 159.251813] el0t_64_sync+0x17c/0x180 ``` mm/kmemleak.c | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 0400f5e8ac60..c77899af3e9e 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -356,14 +356,9 @@ static bool unreferenced_object(struct kmemleak_object *object) * Printing of the unreferenced objects information to the seq file. The * print_unreferenced function must be called with the object->lock held. */ -static void print_unreferenced(struct seq_file *seq, +static depot_stack_handle_t print_unreferenced(struct seq_file *seq, struct kmemleak_object *object) { - int i; - unsigned long *entries; - unsigned int nr_entries; - - nr_entries = stack_depot_fetch(object->trace_handle, &entries); warn_or_seq_printf(seq, "unreferenced object 0x%08lx (size %zu):\n", object->pointer, object->size); warn_or_seq_printf(seq, " comm \"%s\", pid %d, jiffies %lu\n", @@ -371,6 +366,23 @@ static void print_unreferenced(struct seq_file *seq, hex_dump_object(seq, object); warn_or_seq_printf(seq, " backtrace (crc %x):\n", object->checksum); + return object->trace_handle; +} + +/* + * Prints stack traces of unreferenced objects outside of the lock context. + * This avoids potential issues with printing pointers that might require + * additional locking. + */ +static void print_stack_trace(struct seq_file *seq, + depot_stack_handle_t h) +{ + int i; + unsigned long *entries; + unsigned int nr_entries; + + nr_entries = stack_depot_fetch(h, &entries); + for (i = 0; i < nr_entries; i++) { void *ptr = (void *)entries[i]; warn_or_seq_printf(seq, " [<%pK>] %pS\n", ptr, ptr); @@ -1621,7 +1633,9 @@ static void kmemleak_cond_resched(struct kmemleak_object *object) */ static void kmemleak_scan(void) { + depot_stack_handle_t stackdepot_handle; struct kmemleak_object *object; + bool do_print = false; struct zone *zone; int __maybe_unused i; int new_leaks = 0; @@ -1783,12 +1797,17 @@ static void kmemleak_scan(void) !(object->flags & OBJECT_REPORTED)) { object->flags |= OBJECT_REPORTED; - if (kmemleak_verbose) - print_unreferenced(NULL, object); + if (kmemleak_verbose) { + stackdepot_handle = print_unreferenced(NULL, object); + do_print = true; + } new_leaks++; } raw_spin_unlock_irq(&object->lock); + if (kmemleak_verbose && do_print) + print_stack_trace(NULL, stackdepot_handle); + } rcu_read_unlock(); @@ -1937,13 +1956,20 @@ static void kmemleak_seq_stop(struct seq_file *seq, void *v) */ static int kmemleak_seq_show(struct seq_file *seq, void *v) { + depot_stack_handle_t stackdepot_handle; struct kmemleak_object *object = v; + bool do_print = false; unsigned long flags; raw_spin_lock_irqsave(&object->lock, flags); - if ((object->flags & OBJECT_REPORTED) && unreferenced_object(object)) - print_unreferenced(seq, object); + if ((object->flags & OBJECT_REPORTED) && unreferenced_object(object)) { + stackdepot_handle = print_unreferenced(seq, object); + do_print = true; + } raw_spin_unlock_irqrestore(&object->lock, flags); + if (do_print) + print_stack_trace(seq, stackdepot_handle); + return 0; }