Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03c05355 authored by Cong Wang's avatar Cong Wang Committed by Samuel Ortiz
Browse files

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: default avatarDmitry Vyukov <dvyukov@google.com>
Signed-off-by: default avatarCong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent 81ca7835
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -509,6 +509,11 @@ static int llcp_sock_getname(struct socket *sock, struct sockaddr *uaddr,
	memset(llcp_addr, 0, sizeof(*llcp_addr));
	*len = sizeof(struct sockaddr_nfc_llcp);

	lock_sock(sk);
	if (!llcp_sock->dev) {
		release_sock(sk);
		return -EBADFD;
	}
	llcp_addr->sa_family = AF_NFC;
	llcp_addr->dev_idx = llcp_sock->dev->idx;
	llcp_addr->target_idx = llcp_sock->target_idx;
@@ -518,6 +523,7 @@ static int llcp_sock_getname(struct socket *sock, struct sockaddr *uaddr,
	llcp_addr->service_name_len = llcp_sock->service_name_len;
	memcpy(llcp_addr->service_name, llcp_sock->service_name,
	       llcp_addr->service_name_len);
	release_sock(sk);

	return 0;
}