about summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
diff options
context:
space:
mode:
authorZalathar <Zalathar@users.noreply.github.com>2025-08-26 12:31:33 +1000
committerZalathar <Zalathar@users.noreply.github.com>2025-08-26 13:07:19 +1000
commitfcff8f7f5a0d4add3c05f57de1b34291746c3c08 (patch)
tree7a88352c86ab0ad81b9dbf7411e83d5a73cf6dff /compiler/rustc_codegen_llvm/src/llvm/ffi.rs
parentd327d651e2583eb601978179f2ca9808f5e243bb (diff)
downloadrust-fcff8f7f5a0d4add3c05f57de1b34291746c3c08.tar.gz
rust-fcff8f7f5a0d4add3c05f57de1b34291746c3c08.zip
Assert that LLVM range-attribute values don't exceed 128 bits
The underlying implementation of `LLVMCreateConstantRangeAttribute` assumes
that each of `LowerWords` and `UpperWords` points to enough u64 values to
define an integer of the specified bit-length, and will encounter UB if that is
not the case.

Our safe wrapper function always passes pointers to `[u64; 2]` arrays,
regardless of the bit-length specified. That's fine in practice, because scalar
primitives never exceed 128 bits, but it is technically a soundness hole in a
safe function.

We can close the soundness hole by explicitly asserting `size_bits <= 128`.
This is effectively just a stricter version of the existing check that the
value must be small enough to fit in `c_uint`.
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/llvm/ffi.rs')
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs12
1 files changed, 9 insertions, 3 deletions
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index fa2802a891f..7c79cba2273 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -1929,11 +1929,17 @@ unsafe extern "C" {
         C: &Context,
         effects: MemoryEffects,
     ) -> &Attribute;
+    /// ## Safety
+    /// - Each of `LowerWords` and `UpperWords` must point to an array that is
+    ///   long enough to fully define an integer of size `NumBits`, i.e. each
+    ///   pointer must point to `NumBits.div_ceil(64)` elements or more.
+    /// - The implementation will make its own copy of the pointed-to `u64`
+    ///   values, so the pointers only need to outlive this function call.
     pub(crate) fn LLVMRustCreateRangeAttribute(
         C: &Context,
-        num_bits: c_uint,
-        lower_words: *const u64,
-        upper_words: *const u64,
+        NumBits: c_uint,
+        LowerWords: *const u64,
+        UpperWords: *const u64,
     ) -> &Attribute;
 
     // Operations on functions