summaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
authorCong Wang <xiyou.wangcong@gmail.com>2016-01-29 20:37:40 +0100
committerSamuel Ortiz <sameo@linux.intel.com>2016-02-25 08:41:01 +0100
commit03c05355543149bf610f4375e8382ee4fc0aaade (patch)
tree6173ee32c1628a3973ec9305611895434ad121e7 /net/nfc
parentNFC: Use GFP_USER for user-controlled kmalloc (diff)
downloadlinux-03c05355543149bf610f4375e8382ee4fc0aaade.tar.xz
linux-03c05355543149bf610f4375e8382ee4fc0aaade.zip
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>
Diffstat (limited to 'net/nfc')
-rw-r--r--net/nfc/llcp_sock.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
index ecf0a0196f18..b9edf5fae6ae 100644
--- a/net/nfc/llcp_sock.c
+++ b/net/nfc/llcp_sock.c
@@ -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;
}