Summary
An Out-of-Bounds write in Android’s rw_t2t_update_lock_attributes
(NFC) could leads to remote code execution.
Product
Android Open Source Project
CVE
CVE-2020-0070
Tested Version
Pixel3a with build id: QQ1A.191205.011 (tag android-10.0.0_r16). (latest publicly available build as of the time of writing) Proxmark3 used is the RDV4.01
Details
In the rw_t2t_update_lock_attributes
function, p_t2t->lock_attr
is written with the index block_count
. This index is incremented in a while loop every time bits_covered
reaches TAGS_BITS_PER_BYTE
(8)1.
if (bits_covered == TAG_BITS_PER_BYTE) {
/* Move to next 8 bytes */
bits_covered = 0;
block_count++;
Now bits_covered
is reset and incremented inside the while loop with condition bytes_covered < bytes_locked_per_lock_bit
, where bytes_covered
is also incremented at the same time.
while (bytes_covered < bytes_locked_per_lock_bit) {
if (p_t2t->lockbyte[num_dyn_lock_bytes].lock_byte &
rw_t2t_mask_bits[xx]) {
/* If the bit is set then it is locked */
p_t2t->lock_attr[block_count] |= 0x01 << bits_covered;
}
bytes_covered++;
bits_covered++;
This means block_count
can be incremented to a maximum of (bytes_locked_per_lock_bit - 1)/8. This while loop is also enclosed in another while loop which repeats while xx < num_lock_bits
2, which can execute a maximum of 8 times3.
num_lock_bits =
b_all_bits_are_locks
? TAG_BITS_PER_BYTE //<------ maximum |num_lock_bits| is 8.
: p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index]
.num_bits %
TAG_BITS_PER_BYTE;
while (xx < num_lock_bits) {
bytes_covered = 0;
while (bytes_covered < bytes_locked_per_lock_bit) {
As bytes_locked_per_lock_bit
is set here 4 to p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index].bytes_locked_per_bit
bytes_locked_per_lock_bit =
p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index]
.bytes_locked_per_bit;
and p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index].bytes_locked_per_bit
takes its value from p_t2t->tlv_value[2]
5, which comes from data supplied by the tag 6
p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset]; //<-- data supplied by the tag
if (p_t2t->bytes_count == 0) {
....
p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit =
(uint8_t)tags_pow(2, ((p_t2t->tlv_value[2] & 0xF0) >> 4));
by supplying a large enough tlv_value[2]
, a malicious tag can cause OOB write during the detection stage.
Impact
If succesfuly exploited, an attacker within NFC range could obtain remote code execution on android device’s NFC daemon.
Coordinated Disclosure Timeline
- 22/01/2020 Reported as issue 148063806, Android ID 148159613.
- 06/04/2020 Fix published in 2020-04-01 Andriod Security patch
Credit
This issue was discovered and reported by GHSL team member @m-y-mo (Man Yue Mo).
Contact
You can contact the GHSL team at securitylab@github.com
, please include the GHSL-2020-010
in any communication regarding this issue.
-
https://android.googlesource.com/platform/system/nfc/+/6eb02b94a0b367a230ed8e41b0ac86652cbe76c8/src/nfc/tags/rw_t2t_ndef.cc#2260 ↩
-
https://android.googlesource.com/platform/system/nfc/+/6eb02b94a0b367a230ed8e41b0ac86652cbe76c8/src/nfc/tags/rw_t2t_ndef.cc#2247 ↩
-
https://android.googlesource.com/platform/system/nfc/+/6eb02b94a0b367a230ed8e41b0ac86652cbe76c8/src/nfc/tags/rw_t2t_ndef.cc#2240 ↩
-
https://android.googlesource.com/platform/system/nfc/+/6eb02b94a0b367a230ed8e41b0ac86652cbe76c8/src/nfc/tags/rw_t2t_ndef.cc#2231 ↩
-
https://android.googlesource.com/platform/system/nfc/+/6eb02b94a0b367a230ed8e41b0ac86652cbe76c8/src/nfc/tags/rw_t2t_ndef.cc#615 ↩
-
https://android.googlesource.com/platform/system/nfc/+/6eb02b94a0b367a230ed8e41b0ac86652cbe76c8/src/nfc/tags/rw_t2t_ndef.cc#605 ↩