-
Notifications
You must be signed in to change notification settings - Fork 240
Open
Description
Split from #361
CFMutableDictionary has multiple really problematic soundness issues:
- The CFDictionaryCreate callback is always
kCFTypeDictionary*CallBacks, despite the default type arguments being *const c_void. This makes it really easy to cause UB with the CFMutableDictionary type, simply by callingCFMutableDictionary::addwith an arbitrary pointer or null. - Again with CFMutableDictionary,
to_untypedtrivially allows casting an arbitrary pointer to a concrete type.
Here's an example of both problems:
#[test]
fn this_is_very_ub() {
let dict: CFMutableDictionary<CFString, CFString> = CFMutableDictionary::new();
let mut dict_untyped = dict.to_untyped();
let test = CFString::new("test");
dict_untyped.add(&test.to_void(), &std::ptr::null());
let val = dict.get(&test);
println!("{}", val.char_len());
}This will cause a crash in safe rust.
To fix this, I believe CFMutableDictionary::to_untyped should return an immutable CFDictionary, preventing the user from creating types from arbitrary pointers. If this is not desirable, then it should be made unsafe. into_untyped is similarly unsound when combined with clone (which simply increases the refcnt).
Additionally, with_capacity should either use NULL KeyCallBacks/ValueCallBacks (making CoreFoundation default to pointer equality and... unsure how hashing works?) or enforce that K/V be TCFType. Similarly, from_CFType_pairs should enforce K, V: TCFType.
Metadata
Metadata
Assignees
Labels
No labels