Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NFC: Close a race condition in llcp_sock_getname()

llcp_sock_getname() checks llcp_sock->dev to make sure
llcp_sock is already connected or bound, however, we could
be in the middle of llcp_sock_bind() where llcp_sock->dev
is bound and llcp_sock->service_name_len is set,
but llcp_sock->service_name is not, in this case we would
lead to copy some bytes from a NULL pointer.

Just lock the sock since this is not a hot path anyway.

Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Cong Wang and committed by
Samuel Ortiz
03c05355 81ca7835

+6
+6
net/nfc/llcp_sock.c
··· 509 509 memset(llcp_addr, 0, sizeof(*llcp_addr)); 510 510 *len = sizeof(struct sockaddr_nfc_llcp); 511 511 512 + lock_sock(sk); 513 + if (!llcp_sock->dev) { 514 + release_sock(sk); 515 + return -EBADFD; 516 + } 512 517 llcp_addr->sa_family = AF_NFC; 513 518 llcp_addr->dev_idx = llcp_sock->dev->idx; 514 519 llcp_addr->target_idx = llcp_sock->target_idx; ··· 523 518 llcp_addr->service_name_len = llcp_sock->service_name_len; 524 519 memcpy(llcp_addr->service_name, llcp_sock->service_name, 525 520 llcp_addr->service_name_len); 521 + release_sock(sk); 526 522 527 523 return 0; 528 524 }