From nobody Mon Jun 8 09:48:02 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (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 428313AFD16 for ; Sat, 30 May 2026 13:56:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780149384; cv=none; b=eDjchtDV+IEow6xh2SfW1iNZr2uB1gwhaAFaTknF9J4eWscBL9ZQmTAOg0/ObYPj/DewWJPSK3Z9xfJkUtl5oK7ZWXcTawzTqPyefWA+oAw4fjIKtNa3kQW8G/JJ1FEAf757BsKlFtn4sGRGG8KZ03Vt6SXocf7008XAwG6u5kY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780149384; c=relaxed/simple; bh=pmx4ZEpoYOpRgg6gKYR4B+RNYN6FOvGSc0DxPefIpK4=; h=Date:From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type: Content-Disposition; b=tfXi9qULu7a2rynn5I7mBKe6V5PMbRcqHWRvZuuJ1jvtwRsifRVeU0Alm/9N2VpsZxa/bf3msUXybQFgQLyjWlTjAn538panXpnDqNoUUZ8+3uTmAkWggLBlKlW6oiZe0PTm/mTWEJuKavMtulZbbOPY9mRfq0dNZjIPgHeeB5k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Gl5Tba9I; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Gl5Tba9I" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780149381; 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; bh=d1QDNrMOnCS1pRlenvxiQnR9fsbomsqCG/uqIyCgmRI=; b=Gl5Tba9IVItR1sOxCb8sZ7RGpSCyN4hXd10njafJs1FaZOdUw4UEWdgKv0QGYJvMhfAXV3 f06yQWX+v6NVCl/1vK69yD7FFpcdWeupU93+02Y+L/HaBnlUw8Rc6GSkKhMO3sZIQcpZjv bWDWMRN1gvBFXThjSwmCQeCD8H9Mdkw= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-495-3D9kpUZiPnSH64OjDespPw-1; Sat, 30 May 2026 09:56:19 -0400 X-MC-Unique: 3D9kpUZiPnSH64OjDespPw-1 X-Mimecast-MFC-AGG-ID: 3D9kpUZiPnSH64OjDespPw_1780149377 Received: from mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.95]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 60B0119560BA; Sat, 30 May 2026 13:56:17 +0000 (UTC) Received: from fedora (unknown [10.44.33.166]) by mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with SMTP id 11FEB1770; Sat, 30 May 2026 13:56:13 +0000 (UTC) Received: by fedora (nbSMTP-1.00) for uid 1000 oleg@redhat.com; Sat, 30 May 2026 15:56:16 +0200 (CEST) Date: Sat, 30 May 2026 15:56:12 +0200 From: Oleg Nesterov To: Andrew Morton Cc: Christian Brauner , David Hildenbrand , Jann Horn , Kees Cook , Lorenzo Stoakes , Michal Hocko , linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH] mm_access: simplify the security checks Message-ID: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline X-Scanned-By: MIMEDefang 3.6 on 10.30.177.95 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 1. Shift the fast-path "mm =3D=3D current->mm" check from may_access_mm() to mm_access(), and do it locklessly. task->mm is not stable but we do not care. We can race with exec, but in this case we pin/return current->mm. This doesn't differ from the case where the target execs after we drop exec_update_lock. All we need for correctness is READ_ONCE() to ensure the compiler won't reload task->mm. This is not enough for KCSAN, but we already have other lockless ->mm LOAD's. We should probably change exec_mmap/ exit_mm to use WRITE_ONCE(). 2. With the change above may_access_mm() doesn't need the "mm" argument, so we do not need to call get_task_mm() beforehand, we can call it only if may_access_mm() suceeds. 2. With the change above, may_access_mm() doesn't need the "mm" argument, so we do not need to call get_task_mm() beforehand. We can call it only if may_access_mm() succeeds. Signed-off-by: Oleg Nesterov --- kernel/fork.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/kernel/fork.c b/kernel/fork.c index b8b651abce8b..3239380ab93b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1381,10 +1381,8 @@ struct mm_struct *get_task_mm(struct task_struct *ta= sk) } EXPORT_SYMBOL_GPL(get_task_mm); =20 -static bool may_access_mm(struct mm_struct *mm, struct task_struct *task, = unsigned int mode) +static bool may_access_mm(struct task_struct *task, unsigned int mode) { - if (mm =3D=3D current->mm) - return true; if (ptrace_may_access(task, mode)) return true; if ((mode & PTRACE_MODE_READ) && perfmon_capable()) @@ -1394,20 +1392,24 @@ static bool may_access_mm(struct mm_struct *mm, str= uct task_struct *task, unsign =20 struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) { - struct mm_struct *mm; - int err; + struct mm_struct *mm =3D READ_ONCE(task->mm); =20 - err =3D down_read_killable(&task->signal->exec_update_lock); - if (err) - return ERR_PTR(err); + if (!mm || (task->flags & PF_KTHREAD)) + return ERR_PTR(-ESRCH); =20 - mm =3D get_task_mm(task); - if (!mm) { - mm =3D ERR_PTR(-ESRCH); - } else if (!may_access_mm(mm, task, mode)) { - mmput(mm); - mm =3D ERR_PTR(-EACCES); + if (mm =3D=3D current->mm) { + mmget(mm); + return mm; } + + if (down_read_killable(&task->signal->exec_update_lock)) + return ERR_PTR(-EINTR); + + if (may_access_mm(task, mode)) + mm =3D get_task_mm(task) ?: ERR_PTR(-ESRCH); + else + mm =3D ERR_PTR(-EACCES); + up_read(&task->signal->exec_update_lock); =20 return mm; --=20 2.52.0