Skip to content

Commit 2c7c9b7

Browse files
committed
Fix leak in set_ex_data
1 parent 456836a commit 2c7c9b7

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

boring/src/ssl/mod.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1948,13 +1948,10 @@ impl SslContextBuilder {
19481948
///
19491949
/// This can be used to provide data to callbacks registered with the context. Use the
19501950
/// `SslContext::new_ex_index` method to create an `Index`.
1951-
///
1952-
/// Note that if this method is called multiple times with the same index, any previous
1953-
/// value stored in the `SslContextBuilder` will be leaked.
19541951
#[corresponds(SSL_CTX_set_ex_data)]
19551952
pub fn set_ex_data<T>(&mut self, index: Index<SslContext, T>, data: T) {
19561953
unsafe {
1957-
self.ctx.set_ex_data(index, data);
1954+
self.ctx.replace_ex_data(index, data);
19581955
}
19591956
}
19601957

boring/src/ssl/test/mod.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,3 +1118,46 @@ fn test_ssl_set_compliance() {
11181118
ssl.set_compliance_policy(CompliancePolicy::NONE)
11191119
.expect_err("Testing expect err if set compliance policy to NONE");
11201120
}
1121+
1122+
#[test]
1123+
fn ex_data_drop() {
1124+
use crate::ssl::SslContextBuilder;
1125+
use std::sync::atomic::AtomicU32;
1126+
use std::sync::atomic::Ordering::Relaxed;
1127+
use std::sync::Arc;
1128+
1129+
struct TrackDrop(Arc<AtomicU32>);
1130+
impl Drop for TrackDrop {
1131+
fn drop(&mut self) {
1132+
self.0.fetch_add(1, Relaxed);
1133+
}
1134+
}
1135+
1136+
let mut ctx = SslContextBuilder::new(SslMethod::tls()).unwrap();
1137+
let index = SslContext::new_ex_index().unwrap();
1138+
let d1 = Arc::new(AtomicU32::new(100));
1139+
let d2 = Arc::new(AtomicU32::new(200));
1140+
let d3 = Arc::new(AtomicU32::new(300));
1141+
ctx.set_ex_data(index, TrackDrop(d1.clone()));
1142+
assert_eq!(100, d1.load(Relaxed));
1143+
assert_eq!(200, d2.load(Relaxed));
1144+
ctx.replace_ex_data(index, TrackDrop(d2.clone()));
1145+
assert_eq!(101, d1.load(Relaxed));
1146+
assert_eq!(200, d2.load(Relaxed));
1147+
ctx.replace_ex_data(index, TrackDrop(d3.clone()));
1148+
assert_eq!(101, d1.load(Relaxed));
1149+
assert_eq!(201, d2.load(Relaxed));
1150+
assert_eq!(300, d3.load(Relaxed));
1151+
drop(ctx);
1152+
assert_eq!(101, d1.load(Relaxed));
1153+
assert_eq!(201, d2.load(Relaxed));
1154+
assert_eq!(301, d3.load(Relaxed));
1155+
1156+
let mut ctx2 = SslContextBuilder::new(SslMethod::tls()).unwrap();
1157+
1158+
ctx2.set_ex_data(index, TrackDrop(d1.clone()));
1159+
ctx2.set_ex_data(index, TrackDrop(d2.clone()));
1160+
drop(ctx2);
1161+
assert_eq!(102, d1.load(Relaxed));
1162+
assert_eq!(202, d2.load(Relaxed));
1163+
}

0 commit comments

Comments
 (0)