In March 2022, security researchers disclosed CVE-2022-26490, a critical buffer overflow in the Linux kernel’s NFC stack, specifically in the st21nfca_connectivity_event_received function. This flaw, present up to version 5.16.12, could allow local attackers—or even malicious NFC inputs—to execute arbitrary code or crash your machine. In this post, we’ll break it down in simple terms, review the code, and show how this vulnerability can be triggered.

Component: Linux kernel's NFC (Near Field Communication) driver

- Affected File: drivers/nfc/st21nfca/se.c

2. Understanding the Context

The Linux kernel supports several NFC chips. STMicroelectronics’ ST21NFCA chip is one such chip. Data transfer to and from the Secure Element (SE) of the NFC chip happens via “events.” One such event, EVT_TRANSACTION, includes a buffer indicating parameters—like the length of the Application Identifier (AID) and associated data.

Here’s the pitfall: the code does not properly check if the “length” fields (which come straight from NFC hardware, which might be controlled by an attacker) match the actual buffer size. All it takes is a specially crafted event to trigger a classic heap buffer overflow!

Here’s the core of the vulnerable code, found deep in drivers/nfc/st21nfca/se.c (before the fix)

static void st21nfca_connectivity_event_received(struct nfc_dev *dev, struct sk_buff *skb)
{
    size_t aid_len;
    size_t params_len;
    u8 *data = skb->data;

    aid_len = data[];
    if (aid_len ==  || aid_len > 16) // 16 is max for AID
        return;

    params_len = data[1 + aid_len];
    if (params_len ==  || params_len > 255)
        return;

    // Unsafe memcpy: DOES NOT CHECK THAT THE BUFFER IS LARGE ENOUGH!
    u8 aid[16];
    u8 params[255];

    memcpy(aid, &data[1], aid_len);
    memcpy(params, &data[2 + aid_len], params_len);  // <- OVERFLOW!
    /* ... */
}


*(Code simplified for clarity)*

Where’s the Bug?

The code assumes that skb->data is at least as long as 2 + aid_len + params_len. But if an attacker supplies a small buffer (through a broken/hostile NFC reader or emulation), they can set high values for aid_len and/or params_len and provide little actual data, so that memcpy will read WAY past the buffer—causing memory corruption.

The attacker needs to

1. Control an NFC event to deliver a carefully crafted buffer to the driver (usually by being in close NFC range or emulating an NFC device).
2. Set malicious values for aid_len and params_len in the event buffer, such that the actual buffer is SMALLER than 2 + aid_len + params_len bytes.
3. Trigger memory corruption, which could crash the kernel (DoS), or—under the right conditions—lead to code execution (root privilege escalation).

If you’re on a vulnerable system, here’s pseudocode to generate a malicious packet

import socket
import struct

# These values try to go over buffer
aid_len = 16
params_len = 255

# Build the malicious buffer: Only supply 4 bytes after initial header!
evil_buffer = bytes([aid_len])       # aid_len = 16 (max legal)
evil_buffer += b'A'*aid_len          # aid
evil_buffer += bytes([params_len])   # params_len = 255
evil_buffer += b'B'*4                # Real params_data (too short!)

# Open a raw socket to the NFC subsystem or use USB/Fuzzing to send this buffer via NFC stack.


This will make the vulnerable driver read way past the end of evil_buffer when it copies params, causing a kernel heap overflow.

5. Mitigation & Fixed Code

The kernel was patched to strictly check that the provided buffer is long enough before copying.

Fixed code snippet

if (skb->len < 2 + aid_len + params_len)
    return; // Not enough data, reject.

memcpy(aid, &data[1], aid_len);
memcpy(params, &data[2 + aid_len], params_len);

See the patch commit: kernel.org patch link

Upgrade Now: If you use the Linux NFC subsystem, upgrade kernel to 5.16.13 or above ASAP.

- Disable Unused Drivers: If you don’t use NFC, unload or blacklist related kernel modules (st21nfca).
- Harden Kernel: Use grsecurity/KASLR/SELinux where possible, and enable kernel hardening options.

7. Further Reading & References

- CVE-2022-26490 at NVD
- Linux Kernel Patch Commit
- Full Disclosure Mailing List Post
- Linux NFC driver code

8. Conclusion

CVE-2022-26490 is a textbook example of how a single unchecked length can open the door to devastating system-level attacks. If you’re running a kernel version up to 5.16.12 and have NFC enabled, apply security patches immediately—or risk potential exploitation from anyone within NFC range.

Timeline

Published on: 03/06/2022 04:15:00 UTC
Last modified on: 07/04/2022 11:15:00 UTC