summaryrefslogtreecommitdiffstats
path: root/rust/quote/format.rs
diff options
context:
space:
mode:
authorAli Ahmet Memis <ali@iusegentoo.com>2026-08-21 01:45:27 +0000
committerStafford Horne <shorne@gmail.com>2026-08-29 07:32:26 +0100
commit78004e9a87f240df03e2f73120d291763c32e0a7 (patch)
tree137c22dd795222931b9d2bf2501d37cd766741aa /rust/quote/format.rs
downloadlinux-stable-78004e9a87f240df03e2f73120d291763c32e0a7.tar.gz
linux-stable-78004e9a87f240df03e2f73120d291763c32e0a7.zip
openrisc: fix arbitrary kernel memory access via or1k_atomic syscallgrafted
sys_or1k_atomic() (syscall 244 in the "or1k" ABI) takes two user pointers, v1 and v2, and swaps the words they point to in hand-written assembly. l.lwz r29,0(r4) l.lwz r27,0(r5) l.sw 0(r4),r27 l.sw 0(r5),r29 The pointers are not checked with access_ok(). The four memory accesses also have no exception table entries. A caller passes a kernel address as either pointer, and the syscall reads from and writes to it directly. This gives an unprivileged process a kernel read/write primitive. It overwrites kernel data such as the sys_call_table, gaining code execution in kernel context. Check both pointers before entering the critical section. Add fixups for the four memory accesses so faults on valid but unmapped user addresses return -EFAULT. [shorne@gmail.com: fix comment style] Fixes: 9d02a4283e9c ("OpenRISC: Boot code") Cc: stable@vger.kernel.org Signed-off-by: Ali Ahmet Memis <ali@iusegentoo.com> Signed-off-by: Stafford Horne <shorne@gmail.com>
Diffstat (limited to 'rust/quote/format.rs')
-rw-r--r--rust/quote/format.rs170
1 files changed, 170 insertions, 0 deletions
diff --git a/rust/quote/format.rs b/rust/quote/format.rs
new file mode 100644
index 000000000..6e3d55b6e
--- /dev/null
+++ b/rust/quote/format.rs
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
+/// Formatting macro for constructing `Ident`s.
+///
+/// <br>
+///
+/// # Syntax
+///
+/// Syntax is copied from the [`format!`] macro, supporting both positional and
+/// named arguments.
+///
+/// Only a limited set of formatting traits are supported. The current mapping
+/// of format types to traits is:
+///
+/// * `{}` ⇒ [`IdentFragment`]
+/// * `{:o}` ⇒ [`Octal`](std::fmt::Octal)
+/// * `{:x}` ⇒ [`LowerHex`](std::fmt::LowerHex)
+/// * `{:X}` ⇒ [`UpperHex`](std::fmt::UpperHex)
+/// * `{:b}` ⇒ [`Binary`](std::fmt::Binary)
+///
+/// See [`std::fmt`] for more information.
+///
+/// <br>
+///
+/// # IdentFragment
+///
+/// Unlike `format!`, this macro uses the [`IdentFragment`] formatting trait by
+/// default. This trait is like `Display`, with a few differences:
+///
+/// * `IdentFragment` is only implemented for a limited set of types, such as
+/// unsigned integers and strings.
+/// * [`Ident`] arguments will have their `r#` prefixes stripped, if present.
+///
+/// [`IdentFragment`]: crate::IdentFragment
+/// [`Ident`]: proc_macro2::Ident
+///
+/// <br>
+///
+/// # Hygiene
+///
+/// The [`Span`] of the first `Ident` argument is used as the span of the final
+/// identifier, falling back to [`Span::call_site`] when no identifiers are
+/// provided.
+///
+/// ```
+/// # use quote::format_ident;
+/// # let ident = format_ident!("Ident");
+/// // If `ident` is an Ident, the span of `my_ident` will be inherited from it.
+/// let my_ident = format_ident!("My{}{}", ident, "IsCool");
+/// assert_eq!(my_ident, "MyIdentIsCool");
+/// ```
+///
+/// Alternatively, the span can be overridden by passing the `span` named
+/// argument.
+///
+/// ```
+/// # use quote::format_ident;
+/// # const IGNORE_TOKENS: &'static str = stringify! {
+/// let my_span = /* ... */;
+/// # };
+/// # let my_span = proc_macro2::Span::call_site();
+/// format_ident!("MyIdent", span = my_span);
+/// ```
+///
+/// [`Span`]: proc_macro2::Span
+/// [`Span::call_site`]: proc_macro2::Span::call_site
+///
+/// <p><br></p>
+///
+/// # Panics
+///
+/// This method will panic if the resulting formatted string is not a valid
+/// identifier.
+///
+/// <br>
+///
+/// # Examples
+///
+/// Composing raw and non-raw identifiers:
+/// ```
+/// # use quote::format_ident;
+/// let my_ident = format_ident!("My{}", "Ident");
+/// assert_eq!(my_ident, "MyIdent");
+///
+/// let raw = format_ident!("r#Raw");
+/// assert_eq!(raw, "r#Raw");
+///
+/// let my_ident_raw = format_ident!("{}Is{}", my_ident, raw);
+/// assert_eq!(my_ident_raw, "MyIdentIsRaw");
+/// ```
+///
+/// Integer formatting options:
+/// ```
+/// # use quote::format_ident;
+/// let num: u32 = 10;
+///
+/// let decimal = format_ident!("Id_{}", num);
+/// assert_eq!(decimal, "Id_10");
+///
+/// let octal = format_ident!("Id_{:o}", num);
+/// assert_eq!(octal, "Id_12");
+///
+/// let binary = format_ident!("Id_{:b}", num);
+/// assert_eq!(binary, "Id_1010");
+///
+/// let lower_hex = format_ident!("Id_{:x}", num);
+/// assert_eq!(lower_hex, "Id_a");
+///
+/// let upper_hex = format_ident!("Id_{:X}", num);
+/// assert_eq!(upper_hex, "Id_A");
+/// ```
+#[macro_export]
+macro_rules! format_ident {
+ ($fmt:expr) => {
+ $crate::format_ident_impl!([
+ $crate::__private::Option::None,
+ $fmt
+ ])
+ };
+
+ ($fmt:expr, $($rest:tt)*) => {
+ $crate::format_ident_impl!([
+ $crate::__private::Option::None,
+ $fmt
+ ] $($rest)*)
+ };
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! format_ident_impl {
+ // Final state
+ ([$span:expr, $($fmt:tt)*]) => {
+ $crate::__private::mk_ident(
+ &$crate::__private::format!($($fmt)*),
+ $span,
+ )
+ };
+
+ // Span argument
+ ([$old:expr, $($fmt:tt)*] span = $span:expr) => {
+ $crate::format_ident_impl!([$old, $($fmt)*] span = $span,)
+ };
+ ([$old:expr, $($fmt:tt)*] span = $span:expr, $($rest:tt)*) => {
+ $crate::format_ident_impl!([
+ $crate::__private::Option::Some::<$crate::__private::Span>($span),
+ $($fmt)*
+ ] $($rest)*)
+ };
+
+ // Named argument
+ ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr) => {
+ $crate::format_ident_impl!([$span, $($fmt)*] $name = $arg,)
+ };
+ ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr, $($rest:tt)*) => {
+ match $crate::__private::IdentFragmentAdapter(&$arg) {
+ arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, $name = arg] $($rest)*),
+ }
+ };
+
+ // Positional argument
+ ([$span:expr, $($fmt:tt)*] $arg:expr) => {
+ $crate::format_ident_impl!([$span, $($fmt)*] $arg,)
+ };
+ ([$span:expr, $($fmt:tt)*] $arg:expr, $($rest:tt)*) => {
+ match $crate::__private::IdentFragmentAdapter(&$arg) {
+ arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, arg] $($rest)*),
+ }
+ };
+}