aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c103
1 files changed, 57 insertions, 46 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 2b02a3a80313..338837396642 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2,7 +2,7 @@
2 * net/tipc/socket.c: TIPC socket API 2 * net/tipc/socket.c: TIPC socket API
3 * 3 *
4 * Copyright (c) 2001-2007, Ericsson AB 4 * Copyright (c) 2001-2007, Ericsson AB
5 * Copyright (c) 2004-2008, Wind River Systems 5 * Copyright (c) 2004-2008, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -58,6 +58,9 @@ struct tipc_sock {
58#define tipc_sk(sk) ((struct tipc_sock *)(sk)) 58#define tipc_sk(sk) ((struct tipc_sock *)(sk))
59#define tipc_sk_port(sk) ((struct tipc_port *)(tipc_sk(sk)->p)) 59#define tipc_sk_port(sk) ((struct tipc_port *)(tipc_sk(sk)->p))
60 60
61#define tipc_rx_ready(sock) (!skb_queue_empty(&sock->sk->sk_receive_queue) || \
62 (sock->state == SS_DISCONNECTING))
63
61static int backlog_rcv(struct sock *sk, struct sk_buff *skb); 64static int backlog_rcv(struct sock *sk, struct sk_buff *skb);
62static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); 65static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf);
63static void wakeupdispatch(struct tipc_port *tport); 66static void wakeupdispatch(struct tipc_port *tport);
@@ -241,7 +244,6 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol,
241 tipc_set_portunreliable(tp_ptr->ref, 1); 244 tipc_set_portunreliable(tp_ptr->ref, 1);
242 } 245 }
243 246
244 atomic_inc(&tipc_user_count);
245 return 0; 247 return 0;
246} 248}
247 249
@@ -290,7 +292,7 @@ static int release(struct socket *sock)
290 if (buf == NULL) 292 if (buf == NULL)
291 break; 293 break;
292 atomic_dec(&tipc_queue_size); 294 atomic_dec(&tipc_queue_size);
293 if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf))) 295 if (TIPC_SKB_CB(buf)->handle != 0)
294 buf_discard(buf); 296 buf_discard(buf);
295 else { 297 else {
296 if ((sock->state == SS_CONNECTING) || 298 if ((sock->state == SS_CONNECTING) ||
@@ -321,7 +323,6 @@ static int release(struct socket *sock)
321 sock_put(sk); 323 sock_put(sk);
322 sock->sk = NULL; 324 sock->sk = NULL;
323 325
324 atomic_dec(&tipc_user_count);
325 return res; 326 return res;
326} 327}
327 328
@@ -495,6 +496,8 @@ static int dest_name_check(struct sockaddr_tipc *dest, struct msghdr *m)
495 if (likely(dest->addr.name.name.type != TIPC_CFG_SRV)) 496 if (likely(dest->addr.name.name.type != TIPC_CFG_SRV))
496 return -EACCES; 497 return -EACCES;
497 498
499 if (!m->msg_iovlen || (m->msg_iov[0].iov_len < sizeof(hdr)))
500 return -EMSGSIZE;
498 if (copy_from_user(&hdr, m->msg_iov[0].iov_base, sizeof(hdr))) 501 if (copy_from_user(&hdr, m->msg_iov[0].iov_base, sizeof(hdr)))
499 return -EFAULT; 502 return -EFAULT;
500 if ((ntohs(hdr.tcm_type) & 0xC000) && (!capable(CAP_NET_ADMIN))) 503 if ((ntohs(hdr.tcm_type) & 0xC000) && (!capable(CAP_NET_ADMIN)))
@@ -532,6 +535,9 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
532 if (unlikely((m->msg_namelen < sizeof(*dest)) || 535 if (unlikely((m->msg_namelen < sizeof(*dest)) ||
533 (dest->family != AF_TIPC))) 536 (dest->family != AF_TIPC)))
534 return -EINVAL; 537 return -EINVAL;
538 if ((total_len > TIPC_MAX_USER_MSG_SIZE) ||
539 (m->msg_iovlen > (unsigned)INT_MAX))
540 return -EMSGSIZE;
535 541
536 if (iocb) 542 if (iocb)
537 lock_sock(sk); 543 lock_sock(sk);
@@ -570,12 +576,14 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
570 &dest->addr.name.name, 576 &dest->addr.name.name,
571 dest->addr.name.domain, 577 dest->addr.name.domain,
572 m->msg_iovlen, 578 m->msg_iovlen,
573 m->msg_iov); 579 m->msg_iov,
580 total_len);
574 } else if (dest->addrtype == TIPC_ADDR_ID) { 581 } else if (dest->addrtype == TIPC_ADDR_ID) {
575 res = tipc_send2port(tport->ref, 582 res = tipc_send2port(tport->ref,
576 &dest->addr.id, 583 &dest->addr.id,
577 m->msg_iovlen, 584 m->msg_iovlen,
578 m->msg_iov); 585 m->msg_iov,
586 total_len);
579 } else if (dest->addrtype == TIPC_ADDR_MCAST) { 587 } else if (dest->addrtype == TIPC_ADDR_MCAST) {
580 if (needs_conn) { 588 if (needs_conn) {
581 res = -EOPNOTSUPP; 589 res = -EOPNOTSUPP;
@@ -587,7 +595,8 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
587 res = tipc_multicast(tport->ref, 595 res = tipc_multicast(tport->ref,
588 &dest->addr.nameseq, 596 &dest->addr.nameseq,
589 m->msg_iovlen, 597 m->msg_iovlen,
590 m->msg_iov); 598 m->msg_iov,
599 total_len);
591 } 600 }
592 if (likely(res != -ELINKCONG)) { 601 if (likely(res != -ELINKCONG)) {
593 if (needs_conn && (res >= 0)) 602 if (needs_conn && (res >= 0))
@@ -637,6 +646,10 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
637 if (unlikely(dest)) 646 if (unlikely(dest))
638 return send_msg(iocb, sock, m, total_len); 647 return send_msg(iocb, sock, m, total_len);
639 648
649 if ((total_len > TIPC_MAX_USER_MSG_SIZE) ||
650 (m->msg_iovlen > (unsigned)INT_MAX))
651 return -EMSGSIZE;
652
640 if (iocb) 653 if (iocb)
641 lock_sock(sk); 654 lock_sock(sk);
642 655
@@ -649,7 +662,8 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
649 break; 662 break;
650 } 663 }
651 664
652 res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov); 665 res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov,
666 total_len);
653 if (likely(res != -ELINKCONG)) 667 if (likely(res != -ELINKCONG))
654 break; 668 break;
655 if (m->msg_flags & MSG_DONTWAIT) { 669 if (m->msg_flags & MSG_DONTWAIT) {
@@ -720,6 +734,12 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
720 goto exit; 734 goto exit;
721 } 735 }
722 736
737 if ((total_len > (unsigned)INT_MAX) ||
738 (m->msg_iovlen > (unsigned)INT_MAX)) {
739 res = -EMSGSIZE;
740 goto exit;
741 }
742
723 /* 743 /*
724 * Send each iovec entry using one or more messages 744 * Send each iovec entry using one or more messages
725 * 745 *
@@ -750,7 +770,7 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
750 bytes_to_send = curr_left; 770 bytes_to_send = curr_left;
751 my_iov.iov_base = curr_start; 771 my_iov.iov_base = curr_start;
752 my_iov.iov_len = bytes_to_send; 772 my_iov.iov_len = bytes_to_send;
753 res = send_packet(NULL, sock, &my_msg, 0); 773 res = send_packet(NULL, sock, &my_msg, bytes_to_send);
754 if (res < 0) { 774 if (res < 0) {
755 if (bytes_sent) 775 if (bytes_sent)
756 res = bytes_sent; 776 res = bytes_sent;
@@ -911,15 +931,13 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
911 struct tipc_port *tport = tipc_sk_port(sk); 931 struct tipc_port *tport = tipc_sk_port(sk);
912 struct sk_buff *buf; 932 struct sk_buff *buf;
913 struct tipc_msg *msg; 933 struct tipc_msg *msg;
934 long timeout;
914 unsigned int sz; 935 unsigned int sz;
915 u32 err; 936 u32 err;
916 int res; 937 int res;
917 938
918 /* Catch invalid receive requests */ 939 /* Catch invalid receive requests */
919 940
920 if (m->msg_iovlen != 1)
921 return -EOPNOTSUPP; /* Don't do multiple iovec entries yet */
922
923 if (unlikely(!buf_len)) 941 if (unlikely(!buf_len))
924 return -EINVAL; 942 return -EINVAL;
925 943
@@ -930,6 +948,7 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
930 goto exit; 948 goto exit;
931 } 949 }
932 950
951 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
933restart: 952restart:
934 953
935 /* Look for a message in receive queue; wait if necessary */ 954 /* Look for a message in receive queue; wait if necessary */
@@ -939,17 +958,15 @@ restart:
939 res = -ENOTCONN; 958 res = -ENOTCONN;
940 goto exit; 959 goto exit;
941 } 960 }
942 if (flags & MSG_DONTWAIT) { 961 if (timeout <= 0L) {
943 res = -EWOULDBLOCK; 962 res = timeout ? timeout : -EWOULDBLOCK;
944 goto exit; 963 goto exit;
945 } 964 }
946 release_sock(sk); 965 release_sock(sk);
947 res = wait_event_interruptible(*sk_sleep(sk), 966 timeout = wait_event_interruptible_timeout(*sk_sleep(sk),
948 (!skb_queue_empty(&sk->sk_receive_queue) || 967 tipc_rx_ready(sock),
949 (sock->state == SS_DISCONNECTING))); 968 timeout);
950 lock_sock(sk); 969 lock_sock(sk);
951 if (res)
952 goto exit;
953 } 970 }
954 971
955 /* Look at first message in receive queue */ 972 /* Look at first message in receive queue */
@@ -991,11 +1008,10 @@ restart:
991 sz = buf_len; 1008 sz = buf_len;
992 m->msg_flags |= MSG_TRUNC; 1009 m->msg_flags |= MSG_TRUNC;
993 } 1010 }
994 if (unlikely(copy_to_user(m->msg_iov->iov_base, msg_data(msg), 1011 res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg),
995 sz))) { 1012 m->msg_iov, sz);
996 res = -EFAULT; 1013 if (res)
997 goto exit; 1014 goto exit;
998 }
999 res = sz; 1015 res = sz;
1000 } else { 1016 } else {
1001 if ((sock->state == SS_READY) || 1017 if ((sock->state == SS_READY) ||
@@ -1038,19 +1054,15 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1038 struct tipc_port *tport = tipc_sk_port(sk); 1054 struct tipc_port *tport = tipc_sk_port(sk);
1039 struct sk_buff *buf; 1055 struct sk_buff *buf;
1040 struct tipc_msg *msg; 1056 struct tipc_msg *msg;
1057 long timeout;
1041 unsigned int sz; 1058 unsigned int sz;
1042 int sz_to_copy, target, needed; 1059 int sz_to_copy, target, needed;
1043 int sz_copied = 0; 1060 int sz_copied = 0;
1044 char __user *crs = m->msg_iov->iov_base;
1045 unsigned char *buf_crs;
1046 u32 err; 1061 u32 err;
1047 int res = 0; 1062 int res = 0;
1048 1063
1049 /* Catch invalid receive attempts */ 1064 /* Catch invalid receive attempts */
1050 1065
1051 if (m->msg_iovlen != 1)
1052 return -EOPNOTSUPP; /* Don't do multiple iovec entries yet */
1053
1054 if (unlikely(!buf_len)) 1066 if (unlikely(!buf_len))
1055 return -EINVAL; 1067 return -EINVAL;
1056 1068
@@ -1063,7 +1075,7 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1063 } 1075 }
1064 1076
1065 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); 1077 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
1066 1078 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
1067restart: 1079restart:
1068 1080
1069 /* Look for a message in receive queue; wait if necessary */ 1081 /* Look for a message in receive queue; wait if necessary */
@@ -1073,17 +1085,15 @@ restart:
1073 res = -ENOTCONN; 1085 res = -ENOTCONN;
1074 goto exit; 1086 goto exit;
1075 } 1087 }
1076 if (flags & MSG_DONTWAIT) { 1088 if (timeout <= 0L) {
1077 res = -EWOULDBLOCK; 1089 res = timeout ? timeout : -EWOULDBLOCK;
1078 goto exit; 1090 goto exit;
1079 } 1091 }
1080 release_sock(sk); 1092 release_sock(sk);
1081 res = wait_event_interruptible(*sk_sleep(sk), 1093 timeout = wait_event_interruptible_timeout(*sk_sleep(sk),
1082 (!skb_queue_empty(&sk->sk_receive_queue) || 1094 tipc_rx_ready(sock),
1083 (sock->state == SS_DISCONNECTING))); 1095 timeout);
1084 lock_sock(sk); 1096 lock_sock(sk);
1085 if (res)
1086 goto exit;
1087 } 1097 }
1088 1098
1089 /* Look at first message in receive queue */ 1099 /* Look at first message in receive queue */
@@ -1112,24 +1122,25 @@ restart:
1112 /* Capture message data (if valid) & compute return value (always) */ 1122 /* Capture message data (if valid) & compute return value (always) */
1113 1123
1114 if (!err) { 1124 if (!err) {
1115 buf_crs = (unsigned char *)(TIPC_SKB_CB(buf)->handle); 1125 u32 offset = (u32)(unsigned long)(TIPC_SKB_CB(buf)->handle);
1116 sz = (unsigned char *)msg + msg_size(msg) - buf_crs;
1117 1126
1127 sz -= offset;
1118 needed = (buf_len - sz_copied); 1128 needed = (buf_len - sz_copied);
1119 sz_to_copy = (sz <= needed) ? sz : needed; 1129 sz_to_copy = (sz <= needed) ? sz : needed;
1120 if (unlikely(copy_to_user(crs, buf_crs, sz_to_copy))) { 1130
1121 res = -EFAULT; 1131 res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg) + offset,
1132 m->msg_iov, sz_to_copy);
1133 if (res)
1122 goto exit; 1134 goto exit;
1123 } 1135
1124 sz_copied += sz_to_copy; 1136 sz_copied += sz_to_copy;
1125 1137
1126 if (sz_to_copy < sz) { 1138 if (sz_to_copy < sz) {
1127 if (!(flags & MSG_PEEK)) 1139 if (!(flags & MSG_PEEK))
1128 TIPC_SKB_CB(buf)->handle = buf_crs + sz_to_copy; 1140 TIPC_SKB_CB(buf)->handle =
1141 (void *)(unsigned long)(offset + sz_to_copy);
1129 goto exit; 1142 goto exit;
1130 } 1143 }
1131
1132 crs += sz_to_copy;
1133 } else { 1144 } else {
1134 if (sz_copied != 0) 1145 if (sz_copied != 0)
1135 goto exit; /* can't add error msg to valid data */ 1146 goto exit; /* can't add error msg to valid data */
@@ -1256,7 +1267,7 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
1256 1267
1257 /* Enqueue message (finally!) */ 1268 /* Enqueue message (finally!) */
1258 1269
1259 TIPC_SKB_CB(buf)->handle = msg_data(msg); 1270 TIPC_SKB_CB(buf)->handle = 0;
1260 atomic_inc(&tipc_queue_size); 1271 atomic_inc(&tipc_queue_size);
1261 __skb_queue_tail(&sk->sk_receive_queue, buf); 1272 __skb_queue_tail(&sk->sk_receive_queue, buf);
1262 1273
@@ -1608,7 +1619,7 @@ restart:
1608 buf = __skb_dequeue(&sk->sk_receive_queue); 1619 buf = __skb_dequeue(&sk->sk_receive_queue);
1609 if (buf) { 1620 if (buf) {
1610 atomic_dec(&tipc_queue_size); 1621 atomic_dec(&tipc_queue_size);
1611 if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf))) { 1622 if (TIPC_SKB_CB(buf)->handle != 0) {
1612 buf_discard(buf); 1623 buf_discard(buf);
1613 goto restart; 1624 goto restart;
1614 } 1625 }