A recently discovered vulnerability has been resolved in the Linux kernel, specifically related to the Near Field Communications (NFC) subsystem. The vulnerability was found within the llcp_sock_bind/connect operations, resulting in a use-after-free condition. In this post, we will dive into the details of this vulnerability, designated as CVE-2021-47068, discuss its impact, and provide a code snippet to help address the issue.

Problem Background

In the Linux kernel, commits 8a4cd82d ("nfc: fix refcount leak in llcp_sock_connect()") and c33b1cc62 ("nfc: fix refcount leak in llcp_sock_bind()") addressed a refcount leak bug, but they inadvertently introduced a use-after-free vulnerability if the same local is assigned to 2 different sockets. The issue occurs when two sockets are created, each using the same address, which can lead to the use of the freed memory.

This use-after-free vulnerability can be triggered using the following simple program

int sock1 = socket( AF_NFC, SOCK_STREAM, NFC_SOCKPROTO_LLCP );
int sock2 = socket( AF_NFC, SOCK_STREAM, NFC_SOCKPROTO_LLCP );
memset( &addr, , sizeof(struct sockaddr_nfc_llcp) );
addr.sa_family = AF_NFC;
addr.nfc_protocol = NFC_PROTO_NFC_DEP;
bind( sock1, (struct sockaddr*) &addr, sizeof(struct sockaddr_nfc_llcp) );
bind( sock2, (struct sockaddr*) &addr, sizeof(struct sockaddr_nfc_llcp) );
close(sock1);
close(sock2);

The code above creates two sockets, both using the AF_NFC address family and SOCK_STREAM socket type. It then sets the address family and NFC protocol for the sockaddr_nfc_llcp structure and binds both sockets to the same address. Finally, it closes both sockets.

Mitigation and Resolution

To fix this issue, we can simply assign NULL to llcp_sock->local after calling nfc_llcp_local_put. Below is a code snippet to address the vulnerability:

Change the following code in net/nfc/llcp_sock.c

nfc_llcp_local_put(llcp_sock->local);

To:

nfc_llcp_local_put(llcp_sock->local);
llcp_sock->local = NULL;

By adding this line of code, we're ensuring that the local reference in the llcp_sock structure is no longer available for use, effectively mitigating the use-after-free vulnerability.

The information in this post was originally sourced from the following links

- Linux kernel source for net/nfc: https://github.com/torvalds/linux/tree/HEAD/net/nfc
- Changelog for 8a4cd82d: https://github.com/torvalds/linux/commit/8a4cd82db2672fcb923a495488de19287117958d
- Changelog for c33b1cc62: https://github.com/torvalds/linux/commit/c33b1cc623031d46bf9ab51e83a1046dd110e3a2

Conclusion

CVE-2021-47068 is a use-after-free vulnerability in the Linux kernel's NFC subsystem, specifically within the llcp_sock_bind/connect operations. The exploit can be triggered by creating two sockets using the same address, which can lead to the use of freed memory. The resolution involves assigning NULL to the llcp_sock->local variable after calling nfc_llcp_local_put. By making this small change, we can effectively patch the vulnerability and ensure it doesn't pose a risk to users.

Timeline

Published on: 02/29/2024 23:15:08 UTC
Last modified on: 03/01/2024 14:04:26 UTC