Re: [PATCH net] nfc: llcp: fix NULL pointer dereference race in nfc_llcp_send_ui_frame()

David Heidelberg <[email protected]>
Newsgroups dev.linux.lists.oe-linux-nfc,org.kernel.vger.linux-kernel,org.kernel.vger.netdev
Message-ID <[email protected]>
On 25/07/2026 13:55, Junwoong Doh wrote:
> nfc_llcp_send_ui_frame() checks whether sock->local is NULL, but it is
> called by llcp_sock_sendmsg() without the socket lock held, which opens
> a window for a race condition. Between the sock->local check and the
> sock->dev use in nfc_alloc_send_skb(), llcp_sock_bind() can run
> concurrently and set both sock->local and sock->dev to NULL, which can
> lead to a NULL pointer dereference in nfc_alloc_send_skb().
> 
> Take the socket lock in nfc_llcp_send_ui_frame() so that the sock->local
> check and the sock->dev use are performed under it. The message is
> copied from user space before the lock is taken, to avoid holding the
> lock across a user space access that can block for an unbounded amount
> of time.
> 
> Fixes: dded08927ca3 ("nfc: llcp: fix NULL error pointer dereference on sendmsg() after failed bind()")
> Signed-off-by: Junwoong Doh <[email protected]>
> Link: https://lore.kernel.org/all/[email protected]/
> ---
>   net/nfc/llcp_commands.c | 17 ++++++++++++-----
>   1 file changed, 12 insertions(+), 5 deletions(-)
> 
Hello Junwoong,

it seems Sashiko noted an issue, could you verify it please (see below, feel 
free to ignore the pre-existing one)?

Thanks
David

--- Patch [1]: [PATCH net] nfc: llcp: fix NULL pointer dereference race in 
nfc_llcp_send_ui_frame() ---
commit 9c4c4bdf57043772ddc74843af1f533e7e9bc0ca
Author: Junwoong Doh <[email protected]>

nfc: llcp: fix NULL pointer dereference race in nfc_llcp_send_ui_frame()

This patch fixes a race condition in nfc_llcp_send_ui_frame() where
concurrent bind() calls can lead to a NULL pointer dereference. It moves
the allocation and socket state checks inside the socket lock.

Link: https://lore.kernel.org/all/[email protected]/

 > diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c
 > index 291f26facbf3a..cfd5f6aebf8df 100644
 > --- a/net/nfc/llcp_commands.c
 > +++ b/net/nfc/llcp_commands.c
[ ... ]
 > @@ -763,7 +769,7 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 
ssap, u8 dsap,
 >  		pr_debug("Fragment %zd bytes remaining %zd",
 >  			 frag_len, remaining_len);
 >
 > -		pdu = nfc_alloc_send_skb(sock->dev, &sock->sk, 0,
 > +		pdu = nfc_alloc_send_skb(sock->dev, sk, 0,
 >  					 frag_len + LLCP_HEADER_SIZE, &err);

Since the lock_sock(sk) critical section now covers this entire loop, could
calling nfc_alloc_send_skb() with a hardcoded flags value of 0 cause an
uninterruptible sleep deadlock?

When the socket's write buffer is full, sock_alloc_send_skb() will invoke
sock_wait_for_wmem() to sleep until memory is available. For datagram
sockets, this function does not drop the socket lock while sleeping.

Concurrently, any other operations needing the socket lock (such as close()
calling llcp_sock_release) might hang in a D-state indefinitely until the
send buffer drains.

 >  		if (pdu == NULL) {
 >  			pr_err("Could not allocate PDU (error=%d)\n", err);
 >  			len -= remaining_len;

This is a pre-existing issue, but does the exact same race condition remain
unpatched in nfc_llcp_send_i_frame()?

In nfc_llcp_send_i_frame(), llcp_allocate_pdu() is called without holding
the socket lock. If a concurrent disconnect frame transitions the socket to
LLCP_CLOSED, a concurrent failed bind() can set llcp_sock->dev to NULL:

net/nfc/llcp_commands.c:nfc_llcp_send_i_frame() {
     ...
     pdu = llcp_allocate_pdu(sock, LLCP_PDU_I,
                             frag_len + LLCP_SEQUENCE_SIZE);
     ...
}

Which then calls nfc_alloc_send_skb() and dereferences the nullified
sock->dev when computing the headroom:

net/nfc/core.c:nfc_alloc_send_skb() {
     ...
     total_size = size +
             dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE;
     ...
}

Would it be necessary to apply a similar locking fix to
nfc_llcp_send_i_frame() to prevent this NULL pointer dereference?
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.