lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250206181711.1902989-1-elver@google.com>
Date: Thu,  6 Feb 2025 19:09:54 +0100
From: Marco Elver <elver@...gle.com>
To: elver@...gle.com
Cc: "Paul E. McKenney" <paulmck@...nel.org>, Alexander Potapenko <glider@...gle.com>, 
	Bart Van Assche <bvanassche@....org>, Bill Wendling <morbo@...gle.com>, Boqun Feng <boqun.feng@...il.com>, 
	Dmitry Vyukov <dvyukov@...gle.com>, Frederic Weisbecker <frederic@...nel.org>, 
	Greg Kroah-Hartman <gregkh@...uxfoundation.org>, Ingo Molnar <mingo@...nel.org>, 
	Jann Horn <jannh@...gle.com>, Joel Fernandes <joel@...lfernandes.org>, 
	Jonathan Corbet <corbet@....net>, Josh Triplett <josh@...htriplett.org>, 
	Justin Stitt <justinstitt@...gle.com>, Kees Cook <kees@...nel.org>, 
	Mark Rutland <mark.rutland@....com>, Mathieu Desnoyers <mathieu.desnoyers@...icios.com>, 
	Miguel Ojeda <ojeda@...nel.org>, Nathan Chancellor <nathan@...nel.org>, 
	Neeraj Upadhyay <neeraj.upadhyay@...nel.org>, Nick Desaulniers <ndesaulniers@...gle.com>, 
	Peter Zijlstra <peterz@...radead.org>, Steven Rostedt <rostedt@...dmis.org>, 
	Thomas Gleixner <tglx@...utronix.de>, Uladzislau Rezki <urezki@...il.com>, Waiman Long <longman@...hat.com>, 
	Will Deacon <will@...nel.org>, kasan-dev@...glegroups.com, linux-kernel@...r.kernel.org, 
	llvm@...ts.linux.dev, rcu@...r.kernel.org, linux-crypto@...r.kernel.org
Subject: [PATCH RFC 00/24] Compiler-Based Capability- and Locking-Analysis

[ Note: Bart and I had concurrently been working on bringing Clang's
  -Wthread-safety to the kernel:
    https://lore.kernel.org/all/20250206175114.1974171-1-bvanassche@acm.org/
  Having both RFCs out should hopefully provide a good picture on these
  design points and trade-offs - the approaches differ significantly. ]

Capability analysis is a C language extension, which enables statically
checking that user-definable "capabilities" are acquired and released where
required. An obvious application is lock-safety checking for the kernel's
various synchronization primitives (each of which represents a "capability"),
and checking that locking rules are not violated.

Clang originally called the feature "Thread Safety Analysis" [1], with
some terminology still using the thread-safety-analysis-only names. This
was later changed and the feature became more flexible, gaining the
ability to define custom "capabilities". Its foundations can be found in
"capability systems", used to specify the permissibility of operations
to depend on some capability being held (or not held).

[1] https://clang.llvm.org/docs/ThreadSafetyAnalysis.html
[2] https://www.cs.cornell.edu/talc/papers/capabilities.pdf

Because the feature is not just able to express capabilities related to
synchronization primitives, the naming chosen for the kernel departs
from Clang's initial "Thread Safety" nomenclature and refers to the
feature as "Capability Analysis" to avoid confusion. The implementation
still makes references to the older terminology in some places, such as
`-Wthread-safety` being the warning enabled option that also still
appears in diagnostic messages.

Enabling capability analysis can be seen as enabling a dialect of Linux
C with a Capability System.

Additional details can be found in the added kernel-doc documentation.

=== Development Approach ===

Prior art exists in the form of Sparse's context tracking. Locking
annotations on functions exist, so the concept of analyzing locking rules
is not foreign to the kernel's codebase.

However, Clang's analysis is more complete vs. Sparse's, with the
typical trade-offs in static analysis: improved completeness is
sacrificed for more possible false positives or additional annotations
required by the programmer. Numerous options exist to disable or opt out
certain code from analysis.

This series aims to retain compatibility with Sparse, which can provide
tree-wide analysis of a subset of the capability analysis introduced.
For the most part, the new (and old) keywords used for annotations are
shared between Sparse and Clang.

One big question is how to enable this feature, given we end up with a
new dialect of C - 2 approaches have been considered:


	A. Tree-wide all-or-nothing approach. This approach requires
	   tree-wide changes, adding annotations or selective opt-outs.
	   Making additional primitives capability-enabled increases
	   churn, esp. where maintainers are unaware of the feature's
	   existence and how to use it.

Because we can't change the programming language (even if from one C
dialect to another) of the kernel overnight, a different approach might
cause less friction.

	B. A selective, incremental, and much less intrusive approach.
	   Maintainers of subsystems opt in their modules or directories
	   into "capability analysis" (via Makefile):

	     CAPABILITY_ANALYSIS_foo.o := y	# foo.o only
	     CAPABILITY_ANALYSIS := y  		# all TUs

	   Most (eventually all) synchronization primitives and more
	   capabilities (including ones that could track "irq disabled",
	   "preemption" disabled, etc.) could be supported.

The approach taken by this series if B. This ensures that only
subsystems where maintainers are willing to deal with any warnings one
way or another. Introducing the feature can be done incrementally,
without large tree-wide changes and adding numerous opt-outs and
annotations to the majority of code.

=== Initial Uses ===

With this initial series, the following synchronization primitives are
supported: `raw_spinlock_t`, `spinlock_t`, `rwlock_t`, `mutex`,
`seqlock_t`, `bit_spinlock`, RCU, SRCU (`srcu_struct`), `rw_semaphore`,
`local_lock_t`.

As an initial proof-of-concept, this series also enables capability
analysis for the following subsystems: kfence, kcov, stackdepot,
rhashtable. (Those subsystems were chosen because I am familiar with
their locking rules; rhashtable was chosen semi-randomly as a test
because it combines a bunch of things: RCU, mutex, bit_spinlock.)

The initial benefits are static detection of violations of locking
rules. As more capabilities are added, we would see more static checking
beyond what regular C can provide, all while remaining easy (read quick)
to use via the Clang compiler.

=== Appendix ===

The following pending Clang patch is recommended, but not a strong
dependency:

	https://github.com/llvm/llvm-project/pull/123063

This series is also available at this Git tree:

	https://git.kernel.org/pub/scm/linux/kernel/git/melver/linux.git/log/?h=cap-analysis

Marco Elver (24):
  compiler_types: Move lock checking attributes to
    compiler-capability-analysis.h
  compiler-capability-analysis: Rename __cond_lock() to __cond_acquire()
  compiler-capability-analysis: Add infrastructure for Clang's
    capability analysis
  compiler-capability-analysis: Add test stub
  Documentation: Add documentation for Compiler-Based Capability
    Analysis
  checkpatch: Warn about capability_unsafe() without comment
  cleanup: Basic compatibility with capability analysis
  lockdep: Annotate lockdep assertions for capability analysis
  locking/rwlock, spinlock: Support Clang's capability analysis
  compiler-capability-analysis: Change __cond_acquires to take return
    value
  locking/mutex: Support Clang's capability analysis
  locking/seqlock: Support Clang's capability analysis
  bit_spinlock: Include missing <asm/processor.h>
  bit_spinlock: Support Clang's capability analysis
  rcu: Support Clang's capability analysis
  srcu: Support Clang's capability analysis
  kref: Add capability-analysis annotations
  locking/rwsem: Support Clang's capability analysis
  locking/local_lock: Support Clang's capability analysis
  debugfs: Make debugfs_cancellation a capability struct
  kfence: Enable capability analysis
  kcov: Enable capability analysis
  stackdepot: Enable capability analysis
  rhashtable: Enable capability analysis

 .../dev-tools/capability-analysis.rst         | 149 ++++++
 Documentation/dev-tools/index.rst             |   1 +
 Documentation/dev-tools/sparse.rst            |   4 +
 Makefile                                      |   1 +
 .../net/wireless/intel/iwlwifi/iwl-trans.h    |   2 +-
 .../wireless/intel/iwlwifi/pcie/internal.h    |   2 +-
 fs/dlm/lock.c                                 |   2 +-
 include/linux/bit_spinlock.h                  |  24 +-
 include/linux/cleanup.h                       |  18 +-
 include/linux/compiler-capability-analysis.h  | 407 +++++++++++++++
 include/linux/compiler_types.h                |  18 +-
 include/linux/debugfs.h                       |  12 +-
 include/linux/kref.h                          |   2 +
 include/linux/list_bl.h                       |   2 +
 include/linux/local_lock.h                    |  18 +-
 include/linux/local_lock_internal.h           |  41 +-
 include/linux/lockdep.h                       |  12 +-
 include/linux/mm.h                            |   6 +-
 include/linux/mutex.h                         |  29 +-
 include/linux/mutex_types.h                   |   4 +-
 include/linux/rcupdate.h                      |  73 ++-
 include/linux/refcount.h                      |   6 +-
 include/linux/rhashtable.h                    |  14 +-
 include/linux/rwlock.h                        |  27 +-
 include/linux/rwlock_api_smp.h                |  29 +-
 include/linux/rwlock_rt.h                     |  37 +-
 include/linux/rwlock_types.h                  |  10 +-
 include/linux/rwsem.h                         |  56 +-
 include/linux/sched/signal.h                  |   2 +-
 include/linux/seqlock.h                       |  24 +
 include/linux/seqlock_types.h                 |   5 +-
 include/linux/spinlock.h                      |  61 ++-
 include/linux/spinlock_api_smp.h              |  14 +-
 include/linux/spinlock_api_up.h               |  71 +--
 include/linux/spinlock_rt.h                   |  27 +-
 include/linux/spinlock_types.h                |  10 +-
 include/linux/spinlock_types_raw.h            |   5 +-
 include/linux/srcu.h                          |  61 ++-
 kernel/Makefile                               |   2 +
 kernel/kcov.c                                 |  40 +-
 kernel/time/posix-timers.c                    |   2 +-
 lib/Kconfig.debug                             |  43 ++
 lib/Makefile                                  |   6 +
 lib/rhashtable.c                              |  12 +-
 lib/stackdepot.c                              |  24 +-
 lib/test_capability-analysis.c                | 481 ++++++++++++++++++
 mm/kfence/Makefile                            |   2 +
 mm/kfence/core.c                              |  24 +-
 mm/kfence/kfence.h                            |  18 +-
 mm/kfence/kfence_test.c                       |   4 +
 mm/kfence/report.c                            |   8 +-
 net/ipv4/tcp_sigpool.c                        |   2 +-
 scripts/Makefile.capability-analysis          |   5 +
 scripts/Makefile.lib                          |  10 +
 scripts/checkpatch.pl                         |   8 +
 tools/include/linux/compiler_types.h          |   4 +-
 56 files changed, 1682 insertions(+), 299 deletions(-)
 create mode 100644 Documentation/dev-tools/capability-analysis.rst
 create mode 100644 include/linux/compiler-capability-analysis.h
 create mode 100644 lib/test_capability-analysis.c
 create mode 100644 scripts/Makefile.capability-analysis

-- 
2.48.1.502.g6dc24dfdaf-goog


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ