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::add
with an arbitrary pointer or null. - Again with CFMutableDictionary,
to_untyped
trivially 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