aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
authorCong Wang <xiyou.wangcong@gmail.com>2016-01-29 14:37:40 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2016-02-25 02:41:01 -0500
commit03c05355543149bf610f4375e8382ee4fc0aaade (patch)
tree6173ee32c1628a3973ec9305611895434ad121e7 /net/nfc
parent81ca7835f2cb0c3ba4236e3bcf31d997c6f5d71a (diff)
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,
509 memset(llcp_addr, 0, sizeof(*llcp_addr)); 509 memset(llcp_addr, 0, sizeof(*llcp_addr));
510 *len = sizeof(struct sockaddr_nfc_llcp); 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 llcp_addr->sa_family = AF_NFC; 517 llcp_addr->sa_family = AF_NFC;
513 llcp_addr->dev_idx = llcp_sock->dev->idx; 518 llcp_addr->dev_idx = llcp_sock->dev->idx;
514 llcp_addr->target_idx = llcp_sock->target_idx; 519 llcp_addr->target_idx = llcp_sock->target_idx;
@@ -518,6 +523,7 @@ static int llcp_sock_getname(struct socket *sock, struct sockaddr *uaddr,
518 llcp_addr->service_name_len = llcp_sock->service_name_len; 523 llcp_addr->service_name_len = llcp_sock->service_name_len;
519 memcpy(llcp_addr->service_name, llcp_sock->service_name, 524 memcpy(llcp_addr->service_name, llcp_sock->service_name,
520 llcp_addr->service_name_len); 525 llcp_addr->service_name_len);
526 release_sock(sk);
521 527
522 return 0; 528 return 0;
523} 529}