]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
rust: declare cfi_encoding for lru_status
authorAlice Ryhl <aliceryhl@google.com>
Sun, 5 Apr 2026 23:53:07 +0000 (01:53 +0200)
committerMiguel Ojeda <ojeda@kernel.org>
Tue, 7 Apr 2026 08:00:25 +0000 (10:00 +0200)
By default bindgen will convert 'enum lru_status' into a typedef for an
integer. For the most part, an integer of the same size as the enum
results in the correct ABI, but in the specific case of CFI, that is not
the case. The CFI encoding is supposed to be the same as a struct called
'lru_status' rather than the name of the underlying native integer type.

To fix this, tell bindgen to generate a newtype and set the CFI type
explicitly. Note that we need to set the CFI attribute explicitly as
bindgen is using repr(transparent), which is otherwise identical to the
inner type for ABI purposes.

This allows us to remove the page range helper C function in Binder
without risking a CFI failure when list_lru_walk calls the provided
function pointer.

The --with-attribute-custom-enum argument requires bindgen v0.71 or
greater.

[ In particular, the feature was added in 0.71.0 [1][2].

  In addition, `feature(cfi_encoding)` has been available since
  Rust 1.71.0 [3].

Link: https://github.com/rust-lang/rust-bindgen/issues/2520
Link: https://github.com/rust-lang/rust-bindgen/pull/2866
Link: https://github.com/rust-lang/rust/pull/105452
    - Miguel ]

My testing procedure was to add this to the android17-6.18 branch and
verify that rust_shrink_free_page is successfully called without crash,
and verify that it does in fact crash when the cfi_encoding is set to
other values. Note that I couldn't test this on android16-6.12 as that
branch uses a bindgen version that is too old.

Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/20260223-cfi-lru-status-v2-1-89c6448a63a4@google.com
[ Rebased on top of the minimum Rust version bump series which provide
  the required `bindgen` version. - Miguel ]
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260405235309.418950-32-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
drivers/android/binder/Makefile
drivers/android/binder/page_range.rs
drivers/android/binder/page_range_helper.c [deleted file]
drivers/android/binder/page_range_helper.h [deleted file]
rust/bindgen_parameters
rust/bindings/bindings_helper.h
rust/bindings/lib.rs
rust/uapi/lib.rs

index 09eabb527fa092b659559367705fd3667db6cb2c..7e0cd9782a8b24db598034e15e5a36eca91b3fa9 100644 (file)
@@ -5,5 +5,4 @@ obj-$(CONFIG_ANDROID_BINDER_IPC_RUST) += rust_binder.o
 rust_binder-y := \
        rust_binder_main.o      \
        rust_binderfs.o         \
-       rust_binder_events.o    \
-       page_range_helper.o
+       rust_binder_events.o
index fdd97112ef5c8b2341e498dc3567b659f05e3fd7..8e9f5c4819d01e9f87026b0af03aa499a7f72027 100644 (file)
@@ -642,15 +642,15 @@ unsafe extern "C" fn rust_shrink_scan(
     unsafe {
         bindings::list_lru_walk(
             list_lru,
-            Some(bindings::rust_shrink_free_page_wrap),
+            Some(rust_shrink_free_page),
             ptr::null_mut(),
             nr_to_scan,
         )
     }
 }
 
-const LRU_SKIP: bindings::lru_status = bindings::lru_status_LRU_SKIP;
-const LRU_REMOVED_ENTRY: bindings::lru_status = bindings::lru_status_LRU_REMOVED_RETRY;
+const LRU_SKIP: bindings::lru_status = bindings::lru_status::LRU_SKIP;
+const LRU_REMOVED_ENTRY: bindings::lru_status = bindings::lru_status::LRU_REMOVED_RETRY;
 
 /// # Safety
 /// Called by the shrinker.
diff --git a/drivers/android/binder/page_range_helper.c b/drivers/android/binder/page_range_helper.c
deleted file mode 100644 (file)
index 4968877..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/* C helper for page_range.rs to work around a CFI violation.
- *
- * Bindgen currently pretends that `enum lru_status` is the same as an integer.
- * This assumption is fine ABI-wise, but once you add CFI to the mix, it
- * triggers a CFI violation because `enum lru_status` gets a different CFI tag.
- *
- * This file contains a workaround until bindgen can be fixed.
- *
- * Copyright (C) 2025 Google LLC.
- */
-#include "page_range_helper.h"
-
-unsigned int rust_shrink_free_page(struct list_head *item,
-                                  struct list_lru_one *list,
-                                  void *cb_arg);
-
-enum lru_status
-rust_shrink_free_page_wrap(struct list_head *item, struct list_lru_one *list,
-                          void *cb_arg)
-{
-       return rust_shrink_free_page(item, list, cb_arg);
-}
diff --git a/drivers/android/binder/page_range_helper.h b/drivers/android/binder/page_range_helper.h
deleted file mode 100644 (file)
index 18dd2dd..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2025 Google, Inc.
- */
-
-#ifndef _LINUX_PAGE_RANGE_HELPER_H
-#define _LINUX_PAGE_RANGE_HELPER_H
-
-#include <linux/list_lru.h>
-
-enum lru_status
-rust_shrink_free_page_wrap(struct list_head *item, struct list_lru_one *list,
-                          void *cb_arg);
-
-#endif /* _LINUX_PAGE_RANGE_HELPER_H */
index 112ec197ef0a2c6ab68334ca4fee8b6eb9186beb..6f02d9720ad22754833c5c84d5bd19093bee4e9e 100644 (file)
 # warning. We don't need to peek into it anyway.
 --opaque-type spinlock
 
+# enums that appear in indirect function calls should specify a cfi type
+--newtype-enum lru_status
+--with-attribute-custom-enum=lru_status='#[cfi_encoding="10lru_status"]'
+
 # `seccomp`'s comment gets understood as a doctest
 --no-doc-comments
 
index 083cc44aa952c2b29ab82d5d481063a1cf48bccf..faf3ee634ced03bb36e525365b6aef8bd663e4c2 100644 (file)
@@ -149,5 +149,4 @@ const vm_flags_t RUST_CONST_HELPER_VM_NOHUGEPAGE = VM_NOHUGEPAGE;
 #if IS_ENABLED(CONFIG_ANDROID_BINDER_IPC_RUST)
 #include "../../drivers/android/binder/rust_binder.h"
 #include "../../drivers/android/binder/rust_binder_events.h"
-#include "../../drivers/android/binder/page_range_helper.h"
 #endif
index e18c160dad172cedddb6c409f08408b12c3e88b3..854e7c471434c6270185e2b95b2da5959dc15cf0 100644 (file)
@@ -19,6 +19,7 @@
     unreachable_pub,
     unsafe_op_in_unsafe_fn
 )]
+#![feature(cfi_encoding)]
 
 #[allow(dead_code)]
 #[allow(clippy::cast_lossless)]
index 821e286e0daa36424a2cd5d282fdbb989e4eaabf..b8a515de31cae7774f3490aa7e3e440978045e53 100644 (file)
@@ -24,6 +24,7 @@
     unsafe_op_in_unsafe_fn
 )]
 #![cfg_attr(CONFIG_RUSTC_HAS_UNNECESSARY_TRANSMUTES, allow(unnecessary_transmutes))]
+#![feature(cfi_encoding)]
 
 // Manual definition of blocklisted types.
 type __kernel_size_t = usize;