Skip to content

Commit 00438ec

Browse files
GodTamItifraixedes
authored andcommittedJan 20, 2025··
uplink(fix): Do not pass a dangling stack pointer
There were 2 bugs in the `register_gateway_access()` code: 1. Most prominently, the function was constructing and passing a dangling pointer to a temporary `EdgeRegisterAccessOptions` to the FFI. In fact, that variable doesn't even live to the point that the FFI is made. While this occurs on the stack and may not always be overwritten, the compiler and program is free to reclaim and reuse that stack space for other things -- it's technically UB. This code is somewhat lucky that this doesn't occur very often because the struct is very small, on the stack, and a boolean. 2. The function was also casting the `*const EdgeRegisterAccessOptions` pointer as mutable in the unsafe block, which violates Rust's aliasing guarantees and can potentially lead to undefined behavior.
1 parent ea72aad commit 00438ec

File tree

1 file changed

+7
-10
lines changed

1 file changed

+7
-10
lines changed
 

‎uplink/src/edge/config.rs

+7-10
Original file line numberDiff line numberDiff line change
@@ -113,20 +113,17 @@ impl Config {
113113
access: &access::Grant,
114114
opts: Option<&OptionsRegisterAccess>,
115115
) -> Result<credentials::Gateway> {
116-
let uc_opts = if let Some(o) = opts {
117-
&o.as_ffi_options_register_access() as *const ulksys::EdgeRegisterAccessOptions
118-
} else {
119-
ptr::null()
120-
};
116+
// N.B.: Be sure to bind the options to a variable that lives long enough to be passed to
117+
// the FFI.
118+
let mut uc_opts = opts.map(|o| o.as_ffi_options_register_access());
119+
let uc_opts_ptr = uc_opts.as_mut().map_or(ptr::null_mut(), |o| {
120+
o as *mut ulksys::EdgeRegisterAccessOptions
121+
});
121122

122123
// SAFETY: we trust the FFI is safe creating an instance of its own types and rely in our
123124
// implemented FFI methods to return valid FFI values with correct lifetimes.
124125
let uc_res = unsafe {
125-
ulksys::edge_register_access(
126-
self.inner,
127-
access.as_ffi_access(),
128-
uc_opts as *mut ulksys::EdgeRegisterAccessOptions,
129-
)
126+
ulksys::edge_register_access(self.inner, access.as_ffi_access(), uc_opts_ptr)
130127
};
131128

132129
credentials::Gateway::from_ffi_credentials_result(uc_res)

0 commit comments

Comments
 (0)
Please sign in to comment.