Skip to content

Commit eddcb09

Browse files
authored
Remove safety check on strong_count < 1. (#32)
Previously, we tried to check against the possibility that C code calls rustls_client_config_free twice. We did this by doing `Arc::from_raw`, then checking if strong_count is < 1. However, this was undefined behavior: deferencing a dangling pointer. https://doc.rust-lang.org/reference/behavior-considered-undefined.html If strong_count went to zero on some previous call, `Arc` would have dropped its contents. That means the pointed-to memory is no longer valid to access, and its contents are undefined. So we might see strong_count of 1,000,000, or -1,000,000, or any other value; or monkeys could fly out of our noses. The C caller can still invoke undefined behavior by calling `rustls_client_config_free` twice, but the previous change tried to detect undefined behavior by invoking undefined behavior, which doesn't work.
1 parent 10cb373 commit eddcb09

File tree

1 file changed

+4
-12
lines changed

1 file changed

+4
-12
lines changed

src/client.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -135,18 +135,10 @@ pub extern "C" fn rustls_client_config_builder_load_roots_from_file(
135135
pub extern "C" fn rustls_client_config_free(config: *const rustls_client_config) {
136136
ffi_panic_boundary_unit! {
137137
let config: &ClientConfig = try_ref_from_ptr!(config, &mut ClientConfig, ());
138-
// To free the client_config, we reconstruct the Arc. It should have a refcount of 1,
139-
// representing the C code's copy. When it drops, that refcount will go down to 0
140-
// and the inner ClientConfig will be dropped.
141-
let arc: Arc<ClientConfig> = unsafe { Arc::from_raw(config) };
142-
let strong_count = Arc::strong_count(&arc);
143-
if strong_count < 1 {
144-
eprintln!(
145-
"rustls_client_config_free: invariant failed: arc.strong_count was < 1: {}. \
146-
You must not free the same client_config multiple times.",
147-
strong_count
148-
);
149-
}
138+
// To free the client_config, we reconstruct the Arc and then drop it. It should
139+
// have a refcount of 1, representing the C code's copy. When it drops, that
140+
// refcount will go down to 0 and the inner ClientConfig will be dropped.
141+
unsafe { drop(Arc::from_raw(config)) };
150142
}
151143
}
152144

0 commit comments

Comments
 (0)