When setting a new keyboard mapping the following code will be reached:
IOHIKeyboardMapper * IOHIKeyboardMapper::keyboardMapper(
IOHIKeyboard * delegate,
const UInt8 * mapping,
UInt32 mappingLength,
bool mappingShouldBeFreed )
{
IOHIKeyboardMapper * me = new IOHIKeyboardMapper;
if (me && !me->init(delegate, mapping, mappingLength, mappingShouldBeFreed))
{
me->free();
If the init method returns false, IOHIKeyboardMapper::free will be called.
bool IOHIKeyboardMapper::init( IOHIKeyboard *delegate,
const UInt8 *map,
UInt32 mappingLen,
bool mappingShouldBeFreed )
{
if (!super::init()) return false;
_delegate = delegate;
if (!parseKeyMapping(map, mappingLen, &_parsedMapping)) return false;
...
_reserved = IONew(ExpansionData, 1);
If the parseKeyMapping method returns false (by supplying a malformed key mapping),
the init function will return early, and won't initialize the _reserved member.
The IOHIKeyboardMapper::free method will call stickyKeysfree() (both _parsedMapping.mapping and _parsedMapping.mappingLen
are non-zero) :
void IOHIKeyboardMapper::free()
{
if (!_parsedMapping.mapping || !_parsedMapping.mappingLen)
return;
stickyKeysfree();
stickyKeysfree attempts to release all member objects which have been initialized:
void IOHIKeyboardMapper::stickyKeysfree (void)
{
// release shift toggle struct
if (_stickyKeys_ShiftToggle)
stickyKeysFreeToggleInfo(_stickyKeys_ShiftToggle);
// release option toggle struct
if (_stickyKeys_OptionToggle)
stickyKeysFreeToggleInfo(_stickyKeys_OptionToggle);
// release on param dict
if (_onParamDict)
_onParamDict->release();
// release off param dict
if (_offParamDict)
_offParamDict->release();
// release off fn param dict
if (_offFnParamDict) <-- (a)
_offFnParamDict->release(); <-- (b)
However, at (a) _offFnParamDict isn't actually a member but the following macro:
#define _offFnParamDict _reserved->offFnParamDict
Since we returned early from IOHIKeyboardMapper::init before _reserved was allocated it's null.
By mapping the null page we can control the value of the offFnParamDict pointer and therefore
control the virtual function call at (b)
|
key_mapping_null_deref.c
4.2 KB
Download
|