diff options
author | Cong Wang <xiyou.wangcong@gmail.com> | 2016-01-29 22:37:40 +0300 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2016-02-25 10:41:01 +0300 |
commit | 03c05355543149bf610f4375e8382ee4fc0aaade (patch) | |
tree | 6173ee32c1628a3973ec9305611895434ad121e7 /net/nfc | |
parent | 81ca7835f2cb0c3ba4236e3bcf31d997c6f5d71a (diff) | |
download | linux-03c05355543149bf610f4375e8382ee4fc0aaade.tar.xz |
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.c | 6 |
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; } |