From nobody Wed Dec 17 01:09:06 2025 Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) (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 65D6C44C76 for ; Wed, 17 Jul 2024 22:12:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.22 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721254360; cv=none; b=EWV+i6ac8HIKJXtHR5QdX8BlHUV5Zz+Na4hNXB8QeMEFpD9xwJmruIF2ah+O/jylsGJTFyHgUqr+ObCR2luXo5Mz6+z7AdpRqJW2fK2mAn2jZQhtpcz6o5WIHnq7e3oo0R5zaCq1wcWp0xLmYbWU2Z9c0KmM0y7qYOamcqRu/cE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721254360; c=relaxed/simple; bh=zWQFTA9w8X7oKpZUTpUmOG+aSt3BRQJhi4BZXYUZYG4=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=o7GoRIKZ4UK8+YQBlGcmQXQABNMmDE0JAP11Bo4VaY3fOANmguL7f4b1q3DRw5HL1USv3I5W5AiYvNK95rT+Er30dDSf7/nPSXpDH/1g7UsxX0zJNO6sHXsTvEVl+0Cx6mhIIFEVMtEbCO4LnBiRRBRMKNUrhTNCLbljPxiecEA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=proton.me; spf=pass smtp.mailfrom=proton.me; dkim=pass (2048-bit key) header.d=proton.me header.i=@proton.me header.b=hLJMBFde; arc=none smtp.client-ip=185.70.43.22 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=proton.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=proton.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=proton.me header.i=@proton.me header.b="hLJMBFde" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proton.me; s=protonmail; t=1721254355; x=1721513555; bh=Ga3ax7yoxWUsj7eOgiOg45vXpnyPceRh9yN8jZOUScg=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=hLJMBFderJFgsmCTtOWwESgTa2BDgBNyusksuaLUF8Vl/6zIivuOMcmsqd7y7xn+L mRNnTjGIrY53VhwCfUAzyfq7GjopeoGj7tmvlw0Z2kBCHpogegTOSexxPBmD8RlTym KlNI0mIF/AaFwyTW4i3o0Rr0msm8mlfSjv6Yyod3Tbe1mHM/zBAGEfQh72b365GnhR 625dlbUBYzSIbGPZByLO6xr0tuGO+r3UZHBBxoYybHuTaZfyBdCZodanz0PW6EHtLZ GE0AqGR0rxCcEOfsS74QRVhD1GAaQcy3DdfFIEsvWGpS8Rcfkm9LlqBH1z3ttsyWp6 Rx3Hv1albMk+Q== Date: Wed, 17 Jul 2024 22:12:29 +0000 To: Jonathan Corbet , Miguel Ojeda , Alex Gaynor , Wedson Almeida Filho , Boqun Feng , Gary Guo , =?utf-8?Q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl From: Benno Lossin Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org Subject: [RFC PATCH 1/5] doc: rust: create safety standard Message-ID: <20240717221133.459589-2-benno.lossin@proton.me> In-Reply-To: <20240717221133.459589-1-benno.lossin@proton.me> References: <20240717221133.459589-1-benno.lossin@proton.me> Feedback-ID: 71780778:user:proton X-Pm-Message-ID: c838ea6125a78d3f4bd97fa4110efacac1210195 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" `unsafe` Rust code in the kernel is required to have safety documentation. This is to ensure the correctness of `unsafe` code and is thus very important. However, at this point in time there does not exist a standard way of writing safety documentation. This leads to confusion, as authors struggle to find the right way to convey their desired intentions. Readers struggle with correctly interpreting the existing documentation. Add the safety standard that will document the meaning of safety documentation. This first document gives an overview of the problem and gives general information about the topic. Signed-off-by: Benno Lossin --- Documentation/rust/general-information.rst | 1 + Documentation/rust/index.rst | 1 + Documentation/rust/safety-standard/index.rst | 246 +++++++++++++++++++ 3 files changed, 248 insertions(+) create mode 100644 Documentation/rust/safety-standard/index.rst diff --git a/Documentation/rust/general-information.rst b/Documentation/rus= t/general-information.rst index e3f388ef4ee4..ddfe4e2e5307 100644 --- a/Documentation/rust/general-information.rst +++ b/Documentation/rust/general-information.rst @@ -54,6 +54,7 @@ the same invocation used for compilation, e.g.:: Please note that Clippy may change code generation, thus it should not be enabled while building a production kernel. =20 +.. _rust-abstractions: =20 Abstractions vs. bindings ------------------------- diff --git a/Documentation/rust/index.rst b/Documentation/rust/index.rst index 46d35bd395cf..968e9aace301 100644 --- a/Documentation/rust/index.rst +++ b/Documentation/rust/index.rst @@ -39,6 +39,7 @@ configurations. quick-start general-information coding-guidelines + safety-standard/index arch-support testing =20 diff --git a/Documentation/rust/safety-standard/index.rst b/Documentation/r= ust/safety-standard/index.rst new file mode 100644 index 000000000000..1cbc8d3dea04 --- /dev/null +++ b/Documentation/rust/safety-standard/index.rst @@ -0,0 +1,246 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. highlight:: rust + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Rust Safety Standard +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Safe Rust code cannot have memory related bugs. This is a guarantee by the= Rust compiler. Of course +it is not without caveats: no compiler bugs, no bugs in the specification = etc. But the possibly most +important caveat is that of ``unsafe`` code. ``unsafe`` code needs to foll= ow certain rules in order +for safe code to enjoy the no-memory-bugs privilege. A simple example of s= uch a rule is that +references must be valid for the duration of their lifetime. If any rule i= s violated, it can lead +to undefined behavior even in safe code! The term undefined behavior in Ru= st has a lot stricter +meaning than in C or C++: UB in Rust is totally forbidden. In C one might = rely on the compiler +implementation to ensure correct code generation, but that is not the case= for Rust. You can read +more about UB in Rust +`here `_. + +If ``unsafe`` code makes our life this difficult, one might ask the questi= on "why do we even need +it?" and the answer to that is that it gives users an escape hatch to do t= hings that the compiler +normally forbids. ``unsafe`` code is a tool that enables programmers to wr= ite more performant code, +or code that interacts with hardware or C. These things are particularly i= mportant in kernel +development. + +The most effective way to prevent issues in ``unsafe`` code is to just not= write ``unsafe`` code in +the first place. That is why minimizing the amount of ``unsafe`` code is v= ery important. For +example, drivers are not allowed to directly interface with the C side. In= stead of directly +communicating with C functions, they interact with Rust abstractions. This= concentrates the usage +of ``unsafe`` code, making it easy to fix issues, since only the abstracti= on needs to be fixed. +Abstractions also allow taking advantage of other Rust language features. = Read more in +:ref:`rust-abstractions`. + +Since the correctness of the abstractions is integral for safe code to als= o be correct, extra effort +is expended to get them right. Part of that is good safety documentation. + +The goals of safety documentation are: + +* reduce the amount of bugs in ``unsafe`` code, +* help readers know why a given piece of ``unsafe`` code is sound, +* help writers write ``unsafe`` code with confidence, +* simplify the work of reviewers. + +This document standardizes safety documentation. The necessity for this is= simple, only a common +language that all parties understand is effective at the above task. We wa= nt to avoid +misunderstandings in safety related matters. An additional benefit is that= programmers will not have +to ponder for the correct phrasing, since they can find it here. + +This document assumes that the reader is familiar with Rust code and under= stands the most important +concepts of ``unsafe`` Rust. It is recommended that the reader has read th= e `Rust Book`_. Since this +document is about safety documentation, almost all examples are going to c= ontain ``unsafe`` code. +For this reason it is also recommended to read the `Rustonomicon`_, one of= the best resources on +``unsafe`` code. + +.. _Rustonomicon: https://doc.rust-lang.org/nomicon/index.html +.. _Rust Book: https://doc.rust-lang.org/stable/book/ + +If you need help coming up with an abstraction, or with writing the safety= documentation for an +abstraction, feel free to reach out on `zulip`_ or the `list`_. + +.. _zulip: https://rust-for-linux.zulipchat.com +.. _list: https://lore.kernel.org/rust-for-linux + +Soundness +=3D=3D=3D=3D=3D=3D=3D=3D=3D + +``unsafe`` operations (e.g. ``unsafe`` functions, dereferencing raw pointe= rs etc.) have certain +conditions that need to be fulfilled in order for the operation to not be = UB. +To evaluate if the ``unsafe`` code usage is correct, one needs to consider= the API that wraps said +``unsafe`` code. If under all possible safe uses of the API, the condition= s for the ``unsafe`` +operation are fulfilled, the API is *sound*. Otherwise it is *unsound*. He= re is a simple example:: + + pub struct Data { + a: usize, + } + + pub fn access_a(data: *mut Data) -> usize { + unsafe { (*data).a } + } + + fn main() { + let mut d =3D Data { a: 42 }; + println!("{}", access_a(&mut d)); + } + +While this example has no UB, the function ``access_a`` is unsound. This i= s because one could just +write the following safe usage:: + + println!("{}", access_a(core::ptr::null_mut())); + +And this would result in a dereference of a null pointer. + +In its essence, a sound API means that if someone only writes safe code, t= hey can never encounter UB +even if they call safe code that calls ``unsafe`` code behind the scenes. + +Because unsoundness issues have the potential for allowing safe code to ex= perience UB, they are +treated similarly to actual bugs with UB. Their fixes should also be inclu= ded in the stable tree. + +Safety Documentation +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +After trying to minimize and remove as much ``unsafe`` code as possible, t= here still is some left. +This is because some things are just not possible in only safe code. This = last part of ``unsafe`` +code must still be correct. Helping with that is the safety documentation:= it meticulously documents +the various requirements and justifications for every line of ``unsafe`` c= ode. That way it can be +ensured that all ``unsafe`` code is sound without anyone needing to know t= he whole kernel at once. +The gist of the idea is this: every ``unsafe`` operation documents its req= uirements and every +location that uses an ``unsafe`` operation documents for every requirement= a justification why they +are fulfilled. If now all requirements and justifications are correct, the= n there can only be sound +``unsafe`` code. + +The ``unsafe`` keywords has two different meanings depending on the contex= t it is used in: + +* granting access to an unchecked operation, +* declaring that something is an unchecked operation. + +In both cases we have to add safety documentation. In the first case, we h= ave to justify why we can +always guarantee that the requirements of the unchecked operation are fulf= illed. In the second case, +we have to list the requirements that have to be fulfilled for the operati= on to be sound. + +In the following sections we will go over each location where ``unsafe`` c= an be used. + +.. _unsafe-Functions: + +``unsafe`` Functions +-------------------- + +``unsafe`` on function declarations is used to state that this function ha= s special requirements +that callers have to ensure when calling the function:: + + unsafe fn foo() { + // ... + } + +These requirements are called the safety requirements of the function. The= se requirements can take +any shape and range from simple requirements like "``ptr_arg`` is valid" (= ``ptr_arg`` refers to some +argument with the type matching ``*mut T`` or ``*const T``) to more comple= x requirements like +"``ptr`` must be valid, point to a ``NUL``-terminated C string, and it mus= t be valid for at least +``'a``. While the returned value is alive, the memory at ``ptr`` must not = be mutated.". + +The safety requirements have to be documented in the so called safety sect= ion:: + + /// + /// + /// + /// + /// # Safety + /// + /// + unsafe fn foo() { + // ... + } + +.. _unsafe-Blocks: + +``unsafe`` Blocks +----------------- + +``unsafe`` code blocks are used to call ``unsafe`` functions and perform b= uilt-in ``unsafe`` +operations such as dereferencing a raw pointer:: + + unsafe { foo() }; + +In order to ensure that all safety requirements of ``unsafe`` operations a= re upheld, a safety +comment is mandatory for all ``unsafe`` blocks. This safety comment needs = to provide a correct +justification for every safety requirements of every operation within the = block:: + + // SAFETY: + unsafe { foo() }; + +For transparency it is best practice to have only a single ``unsafe`` oper= ation per ``unsafe`` +block, since then it is more clear what the justifications are trying to j= ustify. Safe operations +should not be included in the block, since it adds confusion as to which o= peration is the ``unsafe`` +one. In certain cases however it makes it easier to understand if there is= only a single ``unsafe`` +block. For example:: + + // SAFETY: `ptr` is valid for writes. + unsafe { + (*ptr).field1 =3D 42; + (*ptr).field2 =3D 24; + (*ptr).field3 =3D 2442; + } + +In this case it is more readable to not split the block into multiple part= s. + +``unsafe`` Traits +----------------- + +When ``unsafe`` is on a ``trait`` declaration:: + + unsafe trait Foo {} + +The ``trait`` has special requirements for implementing it. Similar to :re= f:`unsafe-Functions`, these +are called safety requirements and need to be documented in the same way:: + + /// + /// + /// + /// + /// # Safety + /// + /// + unsafe trait Foo {} + +``unsafe`` Impls +---------------- + +When ``unsafe`` is on an ``impl`` item:: + + unsafe impl Foo for Bar {} + +The ``Foo`` ``trait`` has to be ``unsafe`` and its safety requirements nee= d to be justified +similarly to :ref:`unsafe-Blocks`:: + + // SAFETY: + unsafe impl Foo for Bar {} + +General Rules +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The general thought behind all rules in the safety standard is that everyt= hing that cannot be +statically checked by the Rust compiler and guaranteed, needs to be either= checked at runtime, or +have to have safety documentation. + +The Kernel uses ``deny(unsafe_op_in_unsafe_fn)``, disallowing ``unsafe`` o= perations to be contained +in ``unsafe`` functions without a surrounding ``unsafe`` block, an example= violating that would be:: + + unsafe fn zero_ptr(ptr: *mut u32) { + *ptr =3D 0; + } + +Denying code like this is becoming the default in modern editions of the R= ust language. It is also +easy to see why we would want to deny such code: where would we put the ``= SAFETY`` comment for the +pointer dereference? + +Further Pages +------------- + +.. toctree:: + :maxdepth: 1 + +.. only:: subproject and html + + Indices + =3D=3D=3D=3D=3D=3D=3D + + * :ref:`genindex` --=20 2.45.1 From nobody Wed Dec 17 01:09:06 2025 Received: from mail-4316.protonmail.ch (mail-4316.protonmail.ch [185.70.43.16]) (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 7C76350297 for ; Wed, 17 Jul 2024 22:12:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721254368; cv=none; b=uuaJC/RGTD8kPhVSeQ797y9SFrD64d7WmA7kTVvw+8nBFJnuxeyK3zb+zQ3GJO9K/DLCPv4UOQpVNXNwjUBkwcGKmOVzfzrVMQ4Ugf9sNbKprvtnJcc9OCrU0v0L73GJfiPbVBBNAAuAfItU2sRUnTdyWJwym0bqU3eSTiOE2uw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721254368; c=relaxed/simple; bh=Y9pTw1o0mi0D9g/rlNNcDb0to08VNUjyU2T6DuPV3Sk=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=KjMDwRI1tr34mKywhOaUsuKIAEAQOV3BhjGktXImfZQrzuQEpC5VH93Yj1qOeKFhn8GMOtrI3/3KxXrjGylUX+lZE+GOjAlCGwtGqmSxQPI1KhA0a9GbAorJssTvtCkxVRBuQMqsDqnunWLbxNANFLZIfgXkT6Q8CDpowv4Nitg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=proton.me; spf=pass smtp.mailfrom=proton.me; dkim=pass (2048-bit key) header.d=proton.me header.i=@proton.me header.b=ah2WwMFb; arc=none smtp.client-ip=185.70.43.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=proton.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=proton.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=proton.me header.i=@proton.me header.b="ah2WwMFb" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proton.me; s=protonmail; t=1721254363; x=1721513563; bh=y29vr5MpVdYdUaBoMLF0I39s2PWZuV3JMS+02+MZ0lQ=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=ah2WwMFbc0IpeMTZpEfYJ0AQRyN/CggWSlM/2dIfYTAuTAwAPo2OLP4vkyhdyYxCs mSyuwP90RvYiyByLRQgJ3zZEQTB0UAdodmgBqWI5uWJld6Ea4U3ir29t+JV0Ru5NyD V6PqXGtSLe/twMqEBWQTwlR17TYAKXzpvhD519be+ededeL4RgScNpfbfd/ZuMiQaT hboX901z/9w2tmQqDWo7k3+xWT8XrzgSbuWhwS0Shqne70jI/ZC7yNI9ncks7HLiaE MV0iqZ+QvkDH0qQXv5Xh+OAYFxjsTk3v6BI/a148sj9C5nt8wVFJZZtY6bLi9tH8sb oPcJj/9mdPGXA== Date: Wed, 17 Jul 2024 22:12:37 +0000 To: Jonathan Corbet , Miguel Ojeda , Alex Gaynor , Wedson Almeida Filho , Boqun Feng , Gary Guo , =?utf-8?Q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl From: Benno Lossin Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org Subject: [RFC PATCH 2/5] doc: rust: safety standard: add examples Message-ID: <20240717221133.459589-3-benno.lossin@proton.me> In-Reply-To: <20240717221133.459589-1-benno.lossin@proton.me> References: <20240717221133.459589-1-benno.lossin@proton.me> Feedback-ID: 71780778:user:proton X-Pm-Message-ID: e95b376a888855bc5a19fc4fdf5906c20e918f31 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add examples of good and bad safety documentation. There aren't many examples at the moment, as I hope to add more during discussions, since coming up with examples on my own is very difficult. Signed-off-by: Benno Lossin --- .../rust/safety-standard/examples.rst | 70 +++++++++++++++++++ Documentation/rust/safety-standard/index.rst | 23 ++++-- 2 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 Documentation/rust/safety-standard/examples.rst diff --git a/Documentation/rust/safety-standard/examples.rst b/Documentatio= n/rust/safety-standard/examples.rst new file mode 100644 index 000000000000..d66ef3f8954a --- /dev/null +++ b/Documentation/rust/safety-standard/examples.rst @@ -0,0 +1,70 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. highlight:: rust + +Examples +=3D=3D=3D=3D=3D=3D=3D=3D + +Unsound APIs +------------ + +Simple Unsound Function +*********************** +:: + + struct Data { + a: usize, + } + + fn access_a(data: *mut Data) -> usize { + unsafe { (*data).a } + } + +One would normally call this function as follows, which does not trigger U= B:: + + fn main() { + let mut d =3D Data { a: 42 }; + println!("{}", access_a(&mut d)); + } + +However, a caller could also call it like this, which triggers UB using on= ly safe code:: + + fn main() { + println!("{}", access_a(core::ptr::null_mut())); + } + +And this would result in a dereference of a null pointer. + + +Sound ``unsafe`` Code +--------------------- + +The Importance of the API Boundary +********************************** + +Is the following API sound?:: + + fn foo(r: &mut u32) { + let ptr: *mut u32 =3D r; + let val; + unsafe { + val =3D *ptr; + *ptr =3D 0; + } + } + +It better be sound, but one could argue that it is unsound, since one coul= d replace the ptr +initialization by ``ptr =3D core::ptr::null_mut()``:: + + fn foo(r: &mut u32) { + let ptr: *mut u32 =3D core::ptr::null_mut(); + let val; + unsafe { + val =3D *ptr; + *ptr =3D 0; + } + } + +But this modification is not allowed, since it goes beyond the API boundar= y of ``foo``. This way +any ``unsafe`` code that relies on surrounding safe code could be shown to= be unsound. Instead one +should only consider safe code using the API, in this case, there is no wa= y to make the code +incorrect, since a reference is always valid to dereference during its lif= etime. diff --git a/Documentation/rust/safety-standard/index.rst b/Documentation/r= ust/safety-standard/index.rst index 1cbc8d3dea04..bebebda06831 100644 --- a/Documentation/rust/safety-standard/index.rst +++ b/Documentation/rust/safety-standard/index.rst @@ -92,21 +92,28 @@ And this would result in a dereference of a null pointe= r. In its essence, a sound API means that if someone only writes safe code, t= hey can never encounter UB even if they call safe code that calls ``unsafe`` code behind the scenes. =20 +For more examples of unsound code see examples.rst. + Because unsoundness issues have the potential for allowing safe code to ex= perience UB, they are -treated similarly to actual bugs with UB. Their fixes should also be inclu= ded in the stable tree. +treated similarly to real UB. Their fixes should also be included in the s= table tree. =20 Safety Documentation =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -After trying to minimize and remove as much ``unsafe`` code as possible, t= here still is some left. -This is because some things are just not possible in only safe code. This = last part of ``unsafe`` -code must still be correct. Helping with that is the safety documentation:= it meticulously documents -the various requirements and justifications for every line of ``unsafe`` c= ode. That way it can be -ensured that all ``unsafe`` code is sound without anyone needing to know t= he whole kernel at once. +No matter how hard one tries to remove ``unsafe`` code, it is impossible t= o completely get rid of it +in the Kernel. There are things that are impossible for safe code. For exa= mple interacting with the +C side. So one can never be completely sure that there are no memory issue= s lurking somewhere. + +This is where safety documentation helps: it meticulously documents the va= rious requirements and +justifications for every line of ``unsafe`` code. That way the risk of wri= ting unsound ``unsafe`` +code is reduced drastically. + The gist of the idea is this: every ``unsafe`` operation documents its req= uirements and every location that uses an ``unsafe`` operation documents for every requirement= a justification why they are fulfilled. If now all requirements and justifications are correct, the= n there can only be sound -``unsafe`` code. +``unsafe`` code. Reducing the global problem of correctness of the whole k= ernel to the correctness +of each and every ``unsafe`` code block makes it a local problem. Local pr= oblems are a lot easier to +handle, since each instance can be fixed/reviewed independently. =20 The ``unsafe`` keywords has two different meanings depending on the contex= t it is used in: =20 @@ -238,6 +245,8 @@ Further Pages .. toctree:: :maxdepth: 1 =20 + examples + .. only:: subproject and html =20 Indices --=20 2.45.1 From nobody Wed Dec 17 01:09:06 2025 Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) (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 BF10456766 for ; Wed, 17 Jul 2024 22:12:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.22 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721254377; cv=none; b=P+SK61L/8x5KGwZAQYaQjuDfHDksnlKvWWQyNP4R+VmX+SP5EXIrp4X//WQlVUTA/ldyW6n0n9LCZH0pbprIwwhGecXAPloFeeeB2y1JLbE7VRf0hj0t2LXPJr/C9UmbRRNfEW2HKxh8gHApKCEgPAeq7WvdsU/5uOf64jOOoTY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721254377; c=relaxed/simple; bh=ONg/nFcBNrIzbLWP0TcanDXAe/zRmgKLYFbZ/oLUcg0=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=YQ4b56Rn1JBiMPiNx4JQ9VVqfRsYJPWNabdtflph65uxYCBvn5GI0XsM2MssOA9H+Smfkk1GZ/Np9b7/L5jLE8kt4YLZ8Lr5qlZhhTGIjM0HBx6aiGVdEyWthY2YVxjHQ6dApy4tqyQpsXMLhSuA6j4LjreS4EmdV6bF3TyPixQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=proton.me; spf=pass smtp.mailfrom=proton.me; dkim=pass (2048-bit key) header.d=proton.me header.i=@proton.me header.b=RUhMl4/e; arc=none smtp.client-ip=185.70.43.22 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=proton.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=proton.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=proton.me header.i=@proton.me header.b="RUhMl4/e" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proton.me; s=protonmail; t=1721254372; x=1721513572; bh=oz6BK2MUmyOZPB0wPkkUnoUOUyDBcVri6eLFVMypisA=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=RUhMl4/eWLf6HlbiTez6FwBvrNoAi+edyyY+hRRYGxHwWl9IPZDq2V+ECsqc8XdnT +iX+m5ic8NGvX0fewA4KstzZN6yg7CQMNbLVB+irTD5j2vWquvMEpvD4UXkUjdyfRx 80zXNd0ESx91KyPfyVFK+bT0k9WMTzCaE9Y8LV7tVb0Q4JgQKED9FD2V4CRshMIQ2r +VQVhSPy8YkMu5r42pubahgC7XZAH3puJFGYcgXAyWW9qlTfakiqg3R22Jr9wg5chr PIfZwo46E6xtE2QmWBsDoPtK+UHN4O5AdnnZumvuW9XIqVnBFF+ushKqckwav3uVIJ yBEq7WTsrnQ5w== Date: Wed, 17 Jul 2024 22:12:45 +0000 To: Jonathan Corbet , Miguel Ojeda , Alex Gaynor , Wedson Almeida Filho , Boqun Feng , Gary Guo , =?utf-8?Q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl From: Benno Lossin Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org Subject: [RFC PATCH 3/5] doc: rust: safety standard: add guarantees and type invariants Message-ID: <20240717221133.459589-4-benno.lossin@proton.me> In-Reply-To: <20240717221133.459589-1-benno.lossin@proton.me> References: <20240717221133.459589-1-benno.lossin@proton.me> Feedback-ID: 71780778:user:proton X-Pm-Message-ID: acfa0d42b8ce024edca46e621c7bf4a4ed0f08fe Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add documents about `# Guarantees` and `# Invariants` sections. Signed-off-by: Benno Lossin --- .../rust/safety-standard/guarantee.rst | 9 +++++++++ Documentation/rust/safety-standard/index.rst | 16 +++++++++++++++ .../rust/safety-standard/type-invariants.rst | 20 +++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 Documentation/rust/safety-standard/guarantee.rst create mode 100644 Documentation/rust/safety-standard/type-invariants.rst diff --git a/Documentation/rust/safety-standard/guarantee.rst b/Documentati= on/rust/safety-standard/guarantee.rst new file mode 100644 index 000000000000..4d8c811c2bed --- /dev/null +++ b/Documentation/rust/safety-standard/guarantee.rst @@ -0,0 +1,9 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Guarantees +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Functions and ``struct``, ``enum`` and ``union`` types can list guarantees= that ``unsafe`` code can +rely upon in the ``# Guarantees`` section. Guarantees are listed in an uno= rdered markdown list. +The wording of guarantees is identical to the wording of requirements.rst.= To refer to the return +value of the function, use ``$ret``. diff --git a/Documentation/rust/safety-standard/index.rst b/Documentation/r= ust/safety-standard/index.rst index bebebda06831..40b17f59709c 100644 --- a/Documentation/rust/safety-standard/index.rst +++ b/Documentation/rust/safety-standard/index.rst @@ -221,6 +221,20 @@ similarly to :ref:`unsafe-Blocks`:: // SAFETY: unsafe impl Foo for Bar {} =20 +Guarantees +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Functions are also allowed to declare certain guarantees that ``unsafe`` c= ode is able to rely upon. +For example when returning a raw pointer, a common guarantee would be to s= tate that it is valid. See +guarantee.rst for more info. Importantly, guarantees can also be given by = safe functions. + +Type Invariants +--------------- + +Type invariants are a kind of guarantee. Like their name suggests, they al= ways hold (invariant -- +never changing). They can only be specified on ``struct``, ``enum`` or ``u= nion`` types. See +type-invariants.rst for more info. + General Rules =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 @@ -246,6 +260,8 @@ Further Pages :maxdepth: 1 =20 examples + guarantee + type-invariants =20 .. only:: subproject and html =20 diff --git a/Documentation/rust/safety-standard/type-invariants.rst b/Docum= entation/rust/safety-standard/type-invariants.rst new file mode 100644 index 000000000000..dd7e9bda80e5 --- /dev/null +++ b/Documentation/rust/safety-standard/type-invariants.rst @@ -0,0 +1,20 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Type Invariants +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +``struct``, ``enum`` and ``union`` types can list type invariants. They ar= e a kind of +:doc:`guarantee ` that ``unsafe`` code can rely upon. They are = listed in an unordered +list in the ``## Invariants`` subsection of the ``# Guarantees`` section. = The wording of invariants +is identical to the wording of requirements.rst. Invariants hold for the e= ntire lifetime of an +object. During the call of the ``drop`` function these invariants may be v= iolated, since objects +that are being dropped can never be observed. + +Objects with invariants need ``INVARIANT`` comments whenever they are cons= tructed or a field with an +invariant is modified. The comment is similar to ``SAFETY`` comments and n= eeds to justify that the +invariant holds. See justifications.rst for how to justify requirements. + +Sometimes it is needed to violate an invariant temporarily. For example wh= en inside of a function +one can temporarily violate the invariant, as long as it is later reestabl= ished and no external code +can observe the violation. These violations must also be documented using = the ``INVARIANT`` +comments. --=20 2.45.1 From nobody Wed Dec 17 01:09:06 2025 Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) (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 07DAB57CB4 for ; Wed, 17 Jul 2024 22:12:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.22 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721254383; cv=none; b=ple1MjdbiRxJZSTovPRqeNYFYunh+I0HVfQqPR8xs+Qidq6aUgHOdqdoyFI2AmGU3iZhxO1LfZLcX2vkrrjaO/Mz1Goe3dp1EJURwYtRJDTG/Lqkd+khOpKoB93+edOtW+4OtANwU6QpEux1c6x9ZDvRmYgVEcimOyiFUrp005E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721254383; c=relaxed/simple; bh=uGuTjev38iC7jpWZFl8UiFqhRmrP3nbVoD8E9LhFjDs=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=dSF/RCakG+5jBqwXtmlZ2CVcYwGR8CnSfOU1BPryGiCmJgGN4fNdb/Nbmfa6vlxuhR+w7q2ITDimM/SqcdPRA7i7PAK9msYfi1p0K91/8aUseQ+m3DztKE3+QnpB5+G7Rgs4s8hZk5vfeyPIzklueRGMTlgpcDf4AuUjnP4786c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=proton.me; spf=pass smtp.mailfrom=proton.me; dkim=pass (2048-bit key) header.d=proton.me header.i=@proton.me header.b=CbKxV1ng; arc=none smtp.client-ip=185.70.43.22 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=proton.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=proton.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=proton.me header.i=@proton.me header.b="CbKxV1ng" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proton.me; s=protonmail; t=1721254378; x=1721513578; bh=z7ju78jvF1rL+El/phSjRSOwLQJ7motRR1uDNwY8R3I=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=CbKxV1ngnebUMQ8V5Bamuobz2yHpbBo6xORUoBfrQcVPCW1wcJ0FMXaTEyctR+rFH n3pSYsG6XHq8bbhd9Xp1gjziBFh21MbK/ZJuvyh9V4DU8RSCsgZYA+qgRbfHdb9Vw5 yeUqVsu22ZwraVCsiSrmCNBXZ0XzaHoF0zgAzl4hkpyrxxS3GkPGUdkf6aKjKONQm2 AG1jJvTKve2kJ/+QfC87gRuZOLm2teTnhcQb9rrc3pJjBaKcalHlS780+dBVyJZkQ+ CswZ8bbmHcw9Zp3pKdBrrfada4wkTqQQQtjJv01+GT/WbJyCfiEijS3S7ZtDJVSyGY XtfXaGU78fLsg== Date: Wed, 17 Jul 2024 22:12:53 +0000 To: Jonathan Corbet , Miguel Ojeda , Alex Gaynor , Wedson Almeida Filho , Boqun Feng , Gary Guo , =?utf-8?Q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl From: Benno Lossin Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org Subject: [RFC PATCH 4/5] doc: rust: safety standard: add safety requirements Message-ID: <20240717221133.459589-5-benno.lossin@proton.me> In-Reply-To: <20240717221133.459589-1-benno.lossin@proton.me> References: <20240717221133.459589-1-benno.lossin@proton.me> Feedback-ID: 71780778:user:proton X-Pm-Message-ID: 956c6cb7fd82d52baaca7d3b61df9674951e79c4 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add standardized safety requirements. Signed-off-by: Benno Lossin --- Documentation/rust/safety-standard/index.rst | 5 ++ .../rust/safety-standard/requirements.rst | 80 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 Documentation/rust/safety-standard/requirements.rst diff --git a/Documentation/rust/safety-standard/index.rst b/Documentation/r= ust/safety-standard/index.rst index 40b17f59709c..2ef82d7dfbd8 100644 --- a/Documentation/rust/safety-standard/index.rst +++ b/Documentation/rust/safety-standard/index.rst @@ -157,6 +157,8 @@ The safety requirements have to be documented in the so= called safety section:: // ... } =20 +See requirements.rst for a full list of standardized safety requirements. + .. _unsafe-Blocks: =20 ``unsafe`` Blocks @@ -208,6 +210,8 @@ are called safety requirements and need to be documente= d in the same way:: /// unsafe trait Foo {} =20 +See requirements.rst for a full list of standardized safety requirements. + ``unsafe`` Impls ---------------- =20 @@ -262,6 +266,7 @@ Further Pages examples guarantee type-invariants + requirements =20 .. only:: subproject and html =20 diff --git a/Documentation/rust/safety-standard/requirements.rst b/Document= ation/rust/safety-standard/requirements.rst new file mode 100644 index 000000000000..b86bfb98179e --- /dev/null +++ b/Documentation/rust/safety-standard/requirements.rst @@ -0,0 +1,80 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. highlight:: rust + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Safety Requirements +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +There are many different kinds of safety requirements. The simplest exampl= e is the validity of raw +pointers. But there is no limit to what they may require. + +Safety requirements are listed in an unordered markdown list in the ``# Sa= fety`` section on +``unsafe fn`` and ``unsafe trait`` items. Each list item should only conta= in a single requirement. +The items should not specify the same requirement multiple times, especial= ly not by expressing it in +different terms. The ``# Safety`` section should only consist of the list= of safety requirements, +if there is additional information, it should be documented in a different= section. + +Common Safety Requirements +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D + ++------------------------+---------------------+--------------------------= -------------------------+ +| Syntax | Meta Variables | Meaning = | +| | | = | ++=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+ +| ``ptr`` is valid for | | Abbreviation for: = | +| reads and writes. | | = | +| | * ``ptr: *mut T`` | * ``ptr`` is valid for re= ads. | +| | | * ``ptr`` is valid for wr= ites. | ++------------------------+---------------------+--------------------------= -------------------------+ +| ``ptr`` is valid for | | Abbreviation for: = | +| reads. | | = | +| | * ``ptr: *const T`` | * ``ptr`` is valid for re= ads up to | +| | | ``size_of::()`` byte= s for the duration of | +| | | this function call. = | ++------------------------+---------------------+--------------------------= -------------------------+ +| ``ptr`` is valid for | | Abbreviation for: = | +| writes. | | = | +| | * ``ptr: *mut T`` | * ``ptr`` is valid for wr= ites up to | +| | | ``size_of::()`` byte= s for the duration of | +| | | this function call. = | ++------------------------+---------------------+--------------------------= -------------------------+ +| ``ptr`` is valid for | | For the duration of ``'a`= `: | +| reads up to ``size`` | | = | +| bytes for the duration | * ``ptr: *const T`` | * The pointer ``ptr`` is = dereferenceable for | +| of ``'a``. | * ``size: usize`` | ``size`` bytes: all byt= es with offset | +| | | ``0..size`` have to be = part of the same | +| | | allocated object and it= has to be alive. | +| | | * No concurrent write ope= ration may occur to | +| | | ``ptr`` at any offset b= etween ``0..size``. | +| | | * The value at ``ptr`` is= a valid instance of | +| | | the type ``T``. = | +| | | = | +| | | Additionally ``ptr`` must= be: | +| | | = | +| | | * non-null, = | +| | | * aligned to ``align_of::= ()`` i.e. | +| | | ``ptr.addr() % align_of= ::() =3D=3D 0``. | ++------------------------+---------------------+--------------------------= -------------------------+ +| ``ptr`` is valid for | | For the duration of ``'a`= `: | +| writes up to ``size`` | | = | +| bytes for the duration | * ``ptr: *mut T`` | * The pointer ``ptr`` is = dereferenceable for | +| of ``'a``. | * ``size: usize`` | ``size`` bytes: all byt= es with offset | +| | | ``0..size`` have to be = part of the same | +| | | allocated object and it= has to be alive. | +| | | * No concurrent read or w= rite operation may occur | +| | | to ``ptr`` at any offse= t between ``0..size``. | +| | | = | +| | | Additionally ``ptr`` must= be: | +| | | = | +| | | * non-null, = | +| | | * aligned to ``align_of::= ()`` i.e. | +| | | ``ptr.addr() % align_of= ::() =3D=3D 0``. | ++------------------------+---------------------+--------------------------= -------------------------+ + + +Custom Safety Requirements +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D + +There are of course situations where the safety requirements listed above = are insufficient. In that +case the author can try to come up with their own safety requirement wordi= ng and ask the reviewers +what they think. If the requirement is common enough, it should be added t= o the list above. --=20 2.45.1 From nobody Wed Dec 17 01:09:06 2025 Received: from mail-4316.protonmail.ch (mail-4316.protonmail.ch [185.70.43.16]) (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 BCD5F6EB7D; Wed, 17 Jul 2024 22:13:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721254395; cv=none; b=igPAUDYpHSSyEHEwJp/+MiCd2RyjTtzZqQBEdMwQ3J8KDWdv9oFRSKI/6MizGHOHY8LKhA6OLf8JQoXpFe8pvvlgpEJxZyTkAp+N9vLbv3uFcA3vTr77PlHUfvRZtnHxzwmTQHBzqLM4iBaf62Fn9q/GPnbS1d27jzW7NIuc3KY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721254395; c=relaxed/simple; bh=SzS73QiMWiEvVE+b2kR/L9XlmDBOUmYyziDiW39xuTI=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=STt6Xa+MJXuAoY7HtciKqgNjJLow4K1/Z2go+2ZWDr5nAtCzAd38+8rQ16NTL9k0uYFNspwgkxk5kNATqmThjZEBXOv2Fvm6tZDmwnpyM35f4F7kz79lbl5Idjf8GIkUpTcicWl2XIen+52W0a657EP/e4xcko3IQDxgbytwueI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=proton.me; spf=pass smtp.mailfrom=proton.me; dkim=pass (2048-bit key) header.d=proton.me header.i=@proton.me header.b=h+Nynthh; arc=none smtp.client-ip=185.70.43.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=proton.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=proton.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=proton.me header.i=@proton.me header.b="h+Nynthh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proton.me; s=mqb22iym45enpg4fxdy2ivo4ta.protonmail; t=1721254388; x=1721513588; bh=9nFMx1FKFdNLaHQF61hemh/G8y0CQiLx5SxJJKIyYVw=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=h+NynthhFVzd3zVECZ3wv2HCOt5XD+hfbpOXkypP/60ILgy7jiMbPcq8EEGguiqcZ s02I9zXoWiRi2D8S5Fpa+N0Aa26s4iTuf40rrpMQo3TIowWoPnj1AuC4IjgfAWllH4 QN1ewS7DmMR6F85g2t1wByapCalmt0CbFuqKpkYK+/4i9i7ra4cixYR6NmiQFRntWM 2ChO6bDIOpWJViNuEp5hlhiqTkwirlF3fFzxnCruhipiqd6RnylClnnkzK3knNuTus QZKuhqOvZeFran0w4LiVG+PTD5niOxQ8gx0WCkwyoHl5IiBcerWIns+3WcMPVKMmCG Z6ISFy+rZbe7Q== Date: Wed, 17 Jul 2024 22:13:01 +0000 To: Jonathan Corbet , Miguel Ojeda , Alex Gaynor , Wedson Almeida Filho , Boqun Feng , Gary Guo , =?utf-8?Q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl From: Benno Lossin Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org Subject: [RFC PATCH 5/5] doc: rust: safety standard: add justifications Message-ID: <20240717221133.459589-6-benno.lossin@proton.me> In-Reply-To: <20240717221133.459589-1-benno.lossin@proton.me> References: <20240717221133.459589-1-benno.lossin@proton.me> Feedback-ID: 71780778:user:proton X-Pm-Message-ID: 73d5a838551154c1c13817a2765de1d74e91bed0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add standardized justifications that are used to justify the safety requirements. Signed-off-by: Benno Lossin --- Documentation/rust/safety-standard/index.rst | 5 +++ .../rust/safety-standard/justifications.rst | 40 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 Documentation/rust/safety-standard/justifications.rst diff --git a/Documentation/rust/safety-standard/index.rst b/Documentation/r= ust/safety-standard/index.rst index 2ef82d7dfbd8..db62ad01ebe0 100644 --- a/Documentation/rust/safety-standard/index.rst +++ b/Documentation/rust/safety-standard/index.rst @@ -191,6 +191,8 @@ block. For example:: =20 In this case it is more readable to not split the block into multiple part= s. =20 +See justifications.rst for a full list of standardized justifications. + ``unsafe`` Traits ----------------- =20 @@ -225,6 +227,8 @@ similarly to :ref:`unsafe-Blocks`:: // SAFETY: unsafe impl Foo for Bar {} =20 +See justifications.rst for a full list of standardized justifications. + Guarantees =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 @@ -267,6 +271,7 @@ Further Pages guarantee type-invariants requirements + justifications =20 .. only:: subproject and html =20 diff --git a/Documentation/rust/safety-standard/justifications.rst b/Docume= ntation/rust/safety-standard/justifications.rst new file mode 100644 index 000000000000..72b6943f3d40 --- /dev/null +++ b/Documentation/rust/safety-standard/justifications.rst @@ -0,0 +1,40 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. highlight:: rust + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Justifications +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Since there are so many different safety-requirements.rst, there are also = many different ways to +justify them. + +Justifications are listed in an unordered markdown list in the ``SAFETY`` = comments on ``unsafe`` +blocks and ``unsafe impl``. The order and elements of the list must match = the list present in the +``# Safety`` section on the respective ``unsafe`` item (e.g. the function = or the trait). + +Common Justifications +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +In order to use the justifications from the table below, first repeat the = safety requirement and +then write ``by `` where justification is from the table be= low. +If you need the conjunction of multiple justifications, then you just inte= rsperse them with "and". + +The term "goal safety requirement" is referring to the requirement that yo= u are trying to justify. + ++---------------------------+---------------------------------------------= -------------------------+ +| Syntax | Meaning/Justified Safety Requirement = | ++=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+ +| function requirements | The goal safety requirement is provided by t= he surrounding function, | +| | as it also has it (or a stronger statement) = as a safety requirement. | ++---------------------------+---------------------------------------------= -------------------------+ +| type invariant of ``T`` | The given safety requirement is provided by = the type invariant of | +| | ``T``, as it also has it (or a stronger stat= ement) as a type | +| | invariant. = | ++---------------------------+---------------------------------------------= -------------------------+ +| reference validity | When turning a (mutable) reference into a po= inter, that pointer will | +| | be valid for reads (and writes). = | ++---------------------------+---------------------------------------------= -------------------------+ +| function guarantee of | The goal safety requirement is provided by t= he called function | +| ``$function`` | ``$function``, as it has it (or a stronger s= tatement) listed as a | +| | :doc:`guarantee `. = | ++---------------------------+---------------------------------------------= -------------------------+ --=20 2.45.1