Apple has shown an open pair of ears and a lively pair of heels in dealing with two lockscreen bugs that it introduced with iOS 7.
Well done, Cupertino!
(To all hardcore Apple fans reading this: that’s not irony. I really mean it.)
The fruity company has just released iOS 7.0.2, fixing the following:
- The flaw found by videodebarraquito that allowed your photos to be shared online from the lockscreen.
- The flaw found by Karam Daoud that meant you could use the emergency call feature to call anyone you liked while the phone was locked.
Apple isn’t saying too much about the first hole, letting on neither how it came about nor what needed fixing.
But the company has been reasonably frank in revealing what caused the second vulnerability:
A NULL dereference existed in the lock screen which would cause it to restart if the emergency call button was tapped repeatedly. While the lock screen was restarting, the call dialer could not get the lock screen state and assumed the device was unlocked, and so allowed non-emergency numbers to be dialed. This issue was addressed by avoiding the NULL dereference.
There are three interesting issues buried in here, and it’s probably worth glancing at all of them.
Firstly, translating into English, a NULL dereference, also known as a null pointer error, is caused by mismanagement of memory.
When you ask the operating system to reserve a block of memory for your program to use, it typically hands you back the actual memory address you’ve been given, as a numerical value.
If you use the wrong address things will usually break; the operating system may or may not notice, and may or may not be able to do something about it.
It’s a common sort of bug to get the address wrong by a small amount – that’s a buffer overflow, where you overshoot or undershoot, possibly only by a single byte.
It’s also a common sort of bug to access some utterly improbable memory address, by completely messing up the pointer variable where the address is stored.
→ A stored address is known as a pointer, because it points at a memory location. That is about as close to “literary” as programming terminology gets.
And it’s also surprisingly common to try to access memory location zero, because in any operating system that takes security seriously, program variables that haven’t yet been initialised automatically have the value zero.
That’s a consistent way of making sure that uninitialised variables don’t contain data left over in memory from before.
A memory address, or pointer, that has the value zero is a NULL pointer, and any attempt to use it is a NULL dereference.
Most operating systems, therefore, deliberately ensure that memory address zero is off limits to all programs, and always trigger an error if anyone tries to access it.
This handily and automatically catches all null pointer errors, as happened here.
Of course, it’s almost impossible to determine what the programmer intended – who knows what memory location was supposed to be used instead?
So the operating system has little choice but to terminate any program that dereferences a null pointer.
Secondly, the interaction between the restarting lockscreen and the call dialling software is what’s known as a race condition.
There’s a point at which the call dialler checks the state of the lockscreen.
If the restarting lockscreen wins the race, and fires up before the dialler gets there, everything works fine; if the dialler wins the race, the lockscreen can’t tell the dialler what it needs to know.
Race conditions can be very hard to debug because they often occur only under unusual or contrived circumstances, as happened here.
(In this case, you can argue that Apple should make other software wait while the lockscreen is restarting, because of the key security function it performs.)
Thirdly, the fact that the dialler assumes the best if it can’t query the lock screen status is a fail open situation.
Fail open can be desirable and correct, even if some aspects of security are reduced: that’s why electrically-operated security doors are typically held locked shut by the presence of power, so a power failure will release the lock and ensure the doors can be opened to let you escape.
(In this case, you can argue that Apple should code things to fail closed: if the lockscreen software doesn’t know or can’t tell you whether the phone is locked or unlocked, treat it as locked, for security’s sake.)
What to do?
You don’t need to know anything that I just told you about pointers, races and failure modes.
Just apply this patch.
Don’t listen to what the hardcore Apple fans might have said, in commenting on our earlier articles, about these not really being bugs “because all you have to do is not lose your phone.”
A locked phone should be locked.