From nobody Mon Feb 9 04:40:37 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 4756531DD8D; Fri, 17 Oct 2025 10:09:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760695757; cv=none; b=KZVhncI7+q21X/BtTZKBOD6nGMarjhB02RE1dtwghUhnW37dUDqp8tlTCXEldryfJAAhPrXr8PjEmrXTzvmd+8bypcrzT9zy79ns1k7o8ud2o2GSFnOxc4YGcSqw+SY1V9wArK09iE/LuLcDIS8GKEIhoP1QAFy26nIxOiMfh9s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760695757; c=relaxed/simple; bh=be/YPhbyQ1P5Ag66r+4v+GEmNWKI0Xs5mB9mAv89AJI=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=oNVWhG2R8+qYlKBhbttReNohieBD2BRXMtyvtQ79LJzzdYvRijNzhRfv0pKyC+J4/fqqNolad3i7ZXZxCsxwmHdQlAJkDkbWqy6Fq+2bD6iX+/MB551z0swbRaUo6IFXYgSmFuDzIP/VdFkFF15D8ZJ+vinmbRSl9FPil8w+Np8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=hta58kDN; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Y3LLmuFY; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="hta58kDN"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Y3LLmuFY" Message-ID: <20251017093030.378863263@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1760695753; 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: references:references; bh=eAYIGd5fXsjzeJJB6qw0P3j1iV5OhzS8DCs61XHs+jU=; b=hta58kDNqoHEEa2fr4giEnDSVUkRAytH2cY/ek52tlnq3qWRDJ1K/krbS6McjLr93cNBLF jxOOuv3MuMs81dQjLKsp+HxNpsnTgQ/AV2HiNeFCNCOEMA5TyQDBQVDNKRi0p4vmte/Iai WI2zvCG2Lc8rTZzJwcobqA4uqJnd7maiACqPzHL4rChOYJNt1asJ1L2zIRm3uzq/0RMLy6 A8wP+wL5pOyhN/8vXVVelN3NXYs+3rSq6QISL6DP0WxsINkHDR0UUbMorXnQDZ6tuIIGZ5 6Pq6J6Lq/6Tl5eVFMQX8rlfddlnMhm/nPPww+gOl4tJKaR40xGv4tlBz/FwRNg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1760695753; 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: references:references; bh=eAYIGd5fXsjzeJJB6qw0P3j1iV5OhzS8DCs61XHs+jU=; b=Y3LLmuFYZAakAFXAg95cIJVuHw48NRZZoUaiDyUbz89qP5xShyqzhFoiUg+TySC0spPGJK LkNvBVMjv0fTtoBA== From: Thomas Gleixner To: LKML Cc: Julia Lawall , Nicolas Palix , kernel test robot , Russell King , linux-arm-kernel@lists.infradead.org, Linus Torvalds , x86@kernel.org, Madhavan Srinivasan , Michael Ellerman , Nicholas Piggin , Christophe Leroy , linuxppc-dev@lists.ozlabs.org, Paul Walmsley , Palmer Dabbelt , linux-riscv@lists.infradead.org, Heiko Carstens , Christian Borntraeger , Sven Schnelle , linux-s390@vger.kernel.org, Mathieu Desnoyers , Andrew Cooper , Peter Zijlstra , Darren Hart , Davidlohr Bueso , =?UTF-8?q?Andr=C3=A9=20Almeida?= , Alexander Viro , Christian Brauner , Jan Kara , linux-fsdevel@vger.kernel.org Subject: [patch V3 09/12] [RFC] coccinelle: misc: Add scoped_masked_$MODE_access() checker script References: <20251017085938.150569636@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 17 Oct 2025 12:09:12 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A common mistake in user access code is that the wrong access mode is selected for starting the user access section. As most architectures map Read and Write modes to ReadWrite this goes often unnoticed for quite some time. Aside of that the scoped user access mechanism requires that the same pointer is used for the actual accessor macros that was handed in to start the scope because the pointer can be modified by the scope begin mechanism if the architecture supports masking. Add a basic (and incomplete) coccinelle script to check for the common issues. The error output is: kernel/futex/futex.h:303:2-17: ERROR: Invalid pointer for unsafe_put_user(p= ) in scoped_masked_user_write_access(to) kernel/futex/futex.h:292:2-17: ERROR: Invalid access mode unsafe_get_user()= in scoped_masked_user_write_access() Not-Yet-Signed-off-by: Thomas Gleixner Cc: Julia Lawall Cc: Nicolas Palix --- scripts/coccinelle/misc/scoped_uaccess.cocci | 108 ++++++++++++++++++++++= +++++ 1 file changed, 108 insertions(+) --- /dev/null +++ b/scripts/coccinelle/misc/scoped_uaccess.cocci @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0-only +/// Validate scoped_masked_user*access() scopes +/// +// Confidence: Zero +// Options: --no-includes --include-headers + +virtual context +virtual report +virtual org + +@initialize:python@ +@@ + +scopemap =3D { + 'scoped_masked_user_read_access_size' : 'scoped_masked_user_read_access= ', + 'scoped_masked_user_write_access_size' : 'scoped_masked_user_write_acces= s', + 'scoped_masked_user_rw_access_size' : 'scoped_masked_user_rw_access', +} + +# Most common accessors. Incomplete list +noaccessmap =3D { + 'scoped_masked_user_read_access' : ('unsafe_put_user', 'unsafe_cop= y_to_user'), + 'scoped_masked_user_write_access' : ('unsafe_get_user', 'unsafe_cop= y_from_user'), +} + +# Most common accessors. Incomplete list +ptrmap =3D { + 'unsafe_put_user' : 1, + 'unsafe_get_user' : 1, + 'unsafe_copy_to_user' : 0, + 'unsafe_copy_from_user' : 0, +} + +print_mode =3D None + +def pr_err(pos, msg): + if print_mode =3D=3D 'R': + coccilib.report.print_report(pos[0], msg) + elif print_mode =3D=3D 'O': + cocci.print_main(msg, pos) + +@r0 depends on report || org@ +iterator name scoped_masked_user_read_access, + scoped_masked_user_read_access_size, + scoped_masked_user_write_access, + scoped_masked_user_write_access_size, + scoped_masked_user_rw_access, + scoped_masked_user_rw_access_size; +iterator scope; +statement S; +@@ + +( +( +scoped_masked_user_read_access(...) S +| +scoped_masked_user_read_access_size(...) S +| +scoped_masked_user_write_access(...) S +| +scoped_masked_user_write_access_size(...) S +| +scoped_masked_user_rw_access(...) S +| +scoped_masked_user_rw_access_size(...) S +) +& +scope(...) S +) + +@script:python depends on r0 && report@ +@@ +print_mode =3D 'R' + +@script:python depends on r0 && org@ +@@ +print_mode =3D 'O' + +@r1@ +expression sp, a0, a1; +iterator r0.scope; +identifier ac; +position p; +@@ + + scope(sp,...) { + <+... + ac@p(a0, a1, ...); + ...+> + } + +@script:python@ +pos << r1.p; +scope << r0.scope; +ac << r1.ac; +sp << r1.sp; +a0 << r1.a0; +a1 << r1.a1; +@@ + +scope =3D scopemap.get(scope, scope) +if ac in noaccessmap.get(scope, []): + pr_err(pos, 'ERROR: Invalid access mode %s() in %s()' %(ac, scope)) + +if ac in ptrmap: + ap =3D (a0, a1)[ptrmap[ac]] + if sp !=3D ap.lstrip('&').split('->')[0].strip(): + pr_err(pos, 'ERROR: Invalid pointer for %s(%s) in %s(%s)' %(ac, ap, = scope, sp))