Description / Steps to reproduce the issue
Impact
An attacker able to force an unsuccessful RFID read operation can force the kernel to disclose kernel stack information. The called may be able to use the stack content information as part of a more complex attack that can allow privilege escalation.
Description
The contactless kernel driver relies on the read operation implemented by mfrc522_read():
static const struct file_operations g_mfrc522fops =
{
mfrc522_open, /* open */
mfrc522_close, /* close */
[[[[mfrc522_read, /* read */]]]]
...
};
The read operation uses mfrc522_picc_select() which has over 400 lines of code and 9 early return statements. An attacker able to inject bad data on the SPI bus between the NuttX-powered host and the MFRC522 IC may be able cause one of the tests in mfrc522_picc_select() to fail. If the call fails, the uninitialized kernel stack contents of uid (a 12-byte struct picc_uid_s) are returned to the user space caller.
static ssize_t [[[[mfrc522_read]]]](FAR struct file *filep, [[[[FAR char *buffer]]]], size_t buflen)
{
...
[[[[FAR struct picc_uid_s uid;]]]]
...
/* Now read the UID */
[[[[mfrc522_picc_select(dev, &uid, 0);]]]]
if ([[[[uid.sak != PICC_TYPE_NOT_COMPLETE]]]])
{
/* TODO: double/triple UID */
if (buffer)
{
[[[[snprintf(buffer, buflen, "0x%02X%02X%02X%02X",
uid.uid_data[0], uid.uid_data[1],
uid.uid_data[2], uid.uid_data[3]);]]]]
return buflen;
}
}
return OK;
}
Since the mfrc522_picc_select() may fail silently, uid is left uninitialized, specifically uid.sak. As such, the verification uid.sak != PICC_TYPE_NOT_COMPLETE is likely to be true and the content of the kernel stack is leaked to the user space caller.
[[[[int]]]] mfrc522_picc_select(FAR struct mfrc522_dev_s *dev, FAR struct picc_uid_s *uid, uint8_t validbits)
{
...
else
{
uid_complete = true;
[[[[uid->sak = resp_buf[0];]]]]
}
}
/* Set correct uid->size */
uid->size = 3 * cascade_level + 1;
return OK;
}
Recommendation
- Before
snprintf() reads uid, it must be initialized: FAR struct picc_uid_s uid = 0;
- Function
mfrc522_read() must check the mfrc522_picc_select() return code, and propagate the error.
On which OS does this issue occur?
[OS: Linux]
What is the version of your OS?
Ubuntu 24.04
NuttX Version
master
Issue Architecture
[Arch: all]
Issue Area
[Area: Drivers]
Host information
No response
Verification
Description / Steps to reproduce the issue
Impact
An attacker able to force an unsuccessful RFID read operation can force the kernel to disclose kernel stack information. The called may be able to use the stack content information as part of a more complex attack that can allow privilege escalation.
Description
The contactless kernel driver relies on the read operation implemented by
mfrc522_read():The read operation uses
mfrc522_picc_select()which has over 400 lines of code and 9 earlyreturnstatements. An attacker able to inject bad data on the SPI bus between the NuttX-powered host and the MFRC522 IC may be able cause one of the tests inmfrc522_picc_select()to fail. If the call fails, the uninitialized kernel stack contents ofuid(a 12-bytestruct picc_uid_s) are returned to the user space caller.Since the
mfrc522_picc_select()may fail silently,uidis left uninitialized, specificallyuid.sak. As such, the verificationuid.sak != PICC_TYPE_NOT_COMPLETEis likely to be true and the content of the kernel stack is leaked to the user space caller.Recommendation
snprintf()readsuid, it must be initialized:FAR struct picc_uid_s uid = 0;mfrc522_read()must check themfrc522_picc_select()return code, and propagate the error.On which OS does this issue occur?
[OS: Linux]
What is the version of your OS?
Ubuntu 24.04
NuttX Version
master
Issue Architecture
[Arch: all]
Issue Area
[Area: Drivers]
Host information
No response
Verification