diff options
Diffstat (limited to 'net/tipc')
| -rw-r--r-- | net/tipc/link.c | 17 | ||||
| -rw-r--r-- | net/tipc/msg.h | 22 | ||||
| -rw-r--r-- | net/tipc/netlink_compat.c | 54 | ||||
| -rw-r--r-- | net/tipc/node.c | 11 | ||||
| -rw-r--r-- | net/tipc/socket.c | 11 | ||||
| -rw-r--r-- | net/tipc/topsrv.c | 2 |
6 files changed, 103 insertions, 14 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index 2792a3cae682..85ad5c0678d0 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
| @@ -1145,7 +1145,7 @@ static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb, | |||
| 1145 | default: | 1145 | default: |
| 1146 | pr_warn("Dropping received illegal msg type\n"); | 1146 | pr_warn("Dropping received illegal msg type\n"); |
| 1147 | kfree_skb(skb); | 1147 | kfree_skb(skb); |
| 1148 | return false; | 1148 | return true; |
| 1149 | }; | 1149 | }; |
| 1150 | } | 1150 | } |
| 1151 | 1151 | ||
| @@ -1425,6 +1425,10 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe, | |||
| 1425 | l->rcv_unacked = 0; | 1425 | l->rcv_unacked = 0; |
| 1426 | } else { | 1426 | } else { |
| 1427 | /* RESET_MSG or ACTIVATE_MSG */ | 1427 | /* RESET_MSG or ACTIVATE_MSG */ |
| 1428 | if (mtyp == ACTIVATE_MSG) { | ||
| 1429 | msg_set_dest_session_valid(hdr, 1); | ||
| 1430 | msg_set_dest_session(hdr, l->peer_session); | ||
| 1431 | } | ||
| 1428 | msg_set_max_pkt(hdr, l->advertised_mtu); | 1432 | msg_set_max_pkt(hdr, l->advertised_mtu); |
| 1429 | strcpy(data, l->if_name); | 1433 | strcpy(data, l->if_name); |
| 1430 | msg_set_size(hdr, INT_H_SIZE + TIPC_MAX_IF_NAME); | 1434 | msg_set_size(hdr, INT_H_SIZE + TIPC_MAX_IF_NAME); |
| @@ -1642,6 +1646,17 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, | |||
| 1642 | rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT); | 1646 | rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT); |
| 1643 | break; | 1647 | break; |
| 1644 | } | 1648 | } |
| 1649 | |||
| 1650 | /* If this endpoint was re-created while peer was ESTABLISHING | ||
| 1651 | * it doesn't know current session number. Force re-synch. | ||
| 1652 | */ | ||
| 1653 | if (mtyp == ACTIVATE_MSG && msg_dest_session_valid(hdr) && | ||
| 1654 | l->session != msg_dest_session(hdr)) { | ||
| 1655 | if (less(l->session, msg_dest_session(hdr))) | ||
| 1656 | l->session = msg_dest_session(hdr) + 1; | ||
| 1657 | break; | ||
| 1658 | } | ||
| 1659 | |||
| 1645 | /* ACTIVATE_MSG serves as PEER_RESET if link is already down */ | 1660 | /* ACTIVATE_MSG serves as PEER_RESET if link is already down */ |
| 1646 | if (mtyp == RESET_MSG || !link_is_up(l)) | 1661 | if (mtyp == RESET_MSG || !link_is_up(l)) |
| 1647 | rc = tipc_link_fsm_evt(l, LINK_PEER_RESET_EVT); | 1662 | rc = tipc_link_fsm_evt(l, LINK_PEER_RESET_EVT); |
diff --git a/net/tipc/msg.h b/net/tipc/msg.h index a0924956bb61..d7e4b8b93f9d 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h | |||
| @@ -360,6 +360,28 @@ static inline void msg_set_bcast_ack(struct tipc_msg *m, u16 n) | |||
| 360 | msg_set_bits(m, 1, 0, 0xffff, n); | 360 | msg_set_bits(m, 1, 0, 0xffff, n); |
| 361 | } | 361 | } |
| 362 | 362 | ||
| 363 | /* Note: reusing bits in word 1 for ACTIVATE_MSG only, to re-synch | ||
| 364 | * link peer session number | ||
| 365 | */ | ||
| 366 | static inline bool msg_dest_session_valid(struct tipc_msg *m) | ||
| 367 | { | ||
| 368 | return msg_bits(m, 1, 16, 0x1); | ||
| 369 | } | ||
| 370 | |||
| 371 | static inline void msg_set_dest_session_valid(struct tipc_msg *m, bool valid) | ||
| 372 | { | ||
| 373 | msg_set_bits(m, 1, 16, 0x1, valid); | ||
| 374 | } | ||
| 375 | |||
| 376 | static inline u16 msg_dest_session(struct tipc_msg *m) | ||
| 377 | { | ||
| 378 | return msg_bits(m, 1, 0, 0xffff); | ||
| 379 | } | ||
| 380 | |||
| 381 | static inline void msg_set_dest_session(struct tipc_msg *m, u16 n) | ||
| 382 | { | ||
| 383 | msg_set_bits(m, 1, 0, 0xffff, n); | ||
| 384 | } | ||
| 363 | 385 | ||
| 364 | /* | 386 | /* |
| 365 | * Word 2 | 387 | * Word 2 |
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 40f5cae623a7..4ad3586da8f0 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c | |||
| @@ -87,6 +87,11 @@ static int tipc_skb_tailroom(struct sk_buff *skb) | |||
| 87 | return limit; | 87 | return limit; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | static inline int TLV_GET_DATA_LEN(struct tlv_desc *tlv) | ||
| 91 | { | ||
| 92 | return TLV_GET_LEN(tlv) - TLV_SPACE(0); | ||
| 93 | } | ||
| 94 | |||
| 90 | static int tipc_add_tlv(struct sk_buff *skb, u16 type, void *data, u16 len) | 95 | static int tipc_add_tlv(struct sk_buff *skb, u16 type, void *data, u16 len) |
| 91 | { | 96 | { |
| 92 | struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(skb); | 97 | struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(skb); |
| @@ -166,6 +171,11 @@ static struct sk_buff *tipc_get_err_tlv(char *str) | |||
| 166 | return buf; | 171 | return buf; |
| 167 | } | 172 | } |
| 168 | 173 | ||
| 174 | static inline bool string_is_valid(char *s, int len) | ||
| 175 | { | ||
| 176 | return memchr(s, '\0', len) ? true : false; | ||
| 177 | } | ||
| 178 | |||
| 169 | static int __tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, | 179 | static int __tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, |
| 170 | struct tipc_nl_compat_msg *msg, | 180 | struct tipc_nl_compat_msg *msg, |
| 171 | struct sk_buff *arg) | 181 | struct sk_buff *arg) |
| @@ -379,6 +389,7 @@ static int tipc_nl_compat_bearer_enable(struct tipc_nl_compat_cmd_doit *cmd, | |||
| 379 | struct nlattr *prop; | 389 | struct nlattr *prop; |
| 380 | struct nlattr *bearer; | 390 | struct nlattr *bearer; |
| 381 | struct tipc_bearer_config *b; | 391 | struct tipc_bearer_config *b; |
| 392 | int len; | ||
| 382 | 393 | ||
| 383 | b = (struct tipc_bearer_config *)TLV_DATA(msg->req); | 394 | b = (struct tipc_bearer_config *)TLV_DATA(msg->req); |
| 384 | 395 | ||
| @@ -386,6 +397,10 @@ static int tipc_nl_compat_bearer_enable(struct tipc_nl_compat_cmd_doit *cmd, | |||
| 386 | if (!bearer) | 397 | if (!bearer) |
| 387 | return -EMSGSIZE; | 398 | return -EMSGSIZE; |
| 388 | 399 | ||
| 400 | len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_BEARER_NAME); | ||
| 401 | if (!string_is_valid(b->name, len)) | ||
| 402 | return -EINVAL; | ||
| 403 | |||
| 389 | if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, b->name)) | 404 | if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, b->name)) |
| 390 | return -EMSGSIZE; | 405 | return -EMSGSIZE; |
| 391 | 406 | ||
| @@ -411,6 +426,7 @@ static int tipc_nl_compat_bearer_disable(struct tipc_nl_compat_cmd_doit *cmd, | |||
| 411 | { | 426 | { |
| 412 | char *name; | 427 | char *name; |
| 413 | struct nlattr *bearer; | 428 | struct nlattr *bearer; |
| 429 | int len; | ||
| 414 | 430 | ||
| 415 | name = (char *)TLV_DATA(msg->req); | 431 | name = (char *)TLV_DATA(msg->req); |
| 416 | 432 | ||
| @@ -418,6 +434,10 @@ static int tipc_nl_compat_bearer_disable(struct tipc_nl_compat_cmd_doit *cmd, | |||
| 418 | if (!bearer) | 434 | if (!bearer) |
| 419 | return -EMSGSIZE; | 435 | return -EMSGSIZE; |
| 420 | 436 | ||
| 437 | len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_BEARER_NAME); | ||
| 438 | if (!string_is_valid(name, len)) | ||
| 439 | return -EINVAL; | ||
| 440 | |||
| 421 | if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, name)) | 441 | if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, name)) |
| 422 | return -EMSGSIZE; | 442 | return -EMSGSIZE; |
| 423 | 443 | ||
| @@ -478,6 +498,7 @@ static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg, | |||
| 478 | struct nlattr *prop[TIPC_NLA_PROP_MAX + 1]; | 498 | struct nlattr *prop[TIPC_NLA_PROP_MAX + 1]; |
| 479 | struct nlattr *stats[TIPC_NLA_STATS_MAX + 1]; | 499 | struct nlattr *stats[TIPC_NLA_STATS_MAX + 1]; |
| 480 | int err; | 500 | int err; |
| 501 | int len; | ||
| 481 | 502 | ||
| 482 | if (!attrs[TIPC_NLA_LINK]) | 503 | if (!attrs[TIPC_NLA_LINK]) |
| 483 | return -EINVAL; | 504 | return -EINVAL; |
| @@ -504,6 +525,11 @@ static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg, | |||
| 504 | return err; | 525 | return err; |
| 505 | 526 | ||
| 506 | name = (char *)TLV_DATA(msg->req); | 527 | name = (char *)TLV_DATA(msg->req); |
| 528 | |||
| 529 | len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME); | ||
| 530 | if (!string_is_valid(name, len)) | ||
| 531 | return -EINVAL; | ||
| 532 | |||
| 507 | if (strcmp(name, nla_data(link[TIPC_NLA_LINK_NAME])) != 0) | 533 | if (strcmp(name, nla_data(link[TIPC_NLA_LINK_NAME])) != 0) |
| 508 | return 0; | 534 | return 0; |
| 509 | 535 | ||
| @@ -644,6 +670,7 @@ static int tipc_nl_compat_media_set(struct sk_buff *skb, | |||
| 644 | struct nlattr *prop; | 670 | struct nlattr *prop; |
| 645 | struct nlattr *media; | 671 | struct nlattr *media; |
| 646 | struct tipc_link_config *lc; | 672 | struct tipc_link_config *lc; |
| 673 | int len; | ||
| 647 | 674 | ||
| 648 | lc = (struct tipc_link_config *)TLV_DATA(msg->req); | 675 | lc = (struct tipc_link_config *)TLV_DATA(msg->req); |
| 649 | 676 | ||
| @@ -651,6 +678,10 @@ static int tipc_nl_compat_media_set(struct sk_buff *skb, | |||
| 651 | if (!media) | 678 | if (!media) |
| 652 | return -EMSGSIZE; | 679 | return -EMSGSIZE; |
| 653 | 680 | ||
| 681 | len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_MEDIA_NAME); | ||
| 682 | if (!string_is_valid(lc->name, len)) | ||
| 683 | return -EINVAL; | ||
| 684 | |||
| 654 | if (nla_put_string(skb, TIPC_NLA_MEDIA_NAME, lc->name)) | 685 | if (nla_put_string(skb, TIPC_NLA_MEDIA_NAME, lc->name)) |
| 655 | return -EMSGSIZE; | 686 | return -EMSGSIZE; |
| 656 | 687 | ||
| @@ -671,6 +702,7 @@ static int tipc_nl_compat_bearer_set(struct sk_buff *skb, | |||
| 671 | struct nlattr *prop; | 702 | struct nlattr *prop; |
| 672 | struct nlattr *bearer; | 703 | struct nlattr *bearer; |
| 673 | struct tipc_link_config *lc; | 704 | struct tipc_link_config *lc; |
| 705 | int len; | ||
| 674 | 706 | ||
| 675 | lc = (struct tipc_link_config *)TLV_DATA(msg->req); | 707 | lc = (struct tipc_link_config *)TLV_DATA(msg->req); |
| 676 | 708 | ||
| @@ -678,6 +710,10 @@ static int tipc_nl_compat_bearer_set(struct sk_buff *skb, | |||
| 678 | if (!bearer) | 710 | if (!bearer) |
| 679 | return -EMSGSIZE; | 711 | return -EMSGSIZE; |
| 680 | 712 | ||
| 713 | len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_MEDIA_NAME); | ||
| 714 | if (!string_is_valid(lc->name, len)) | ||
| 715 | return -EINVAL; | ||
| 716 | |||
| 681 | if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, lc->name)) | 717 | if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, lc->name)) |
| 682 | return -EMSGSIZE; | 718 | return -EMSGSIZE; |
| 683 | 719 | ||
| @@ -726,9 +762,14 @@ static int tipc_nl_compat_link_set(struct tipc_nl_compat_cmd_doit *cmd, | |||
| 726 | struct tipc_link_config *lc; | 762 | struct tipc_link_config *lc; |
| 727 | struct tipc_bearer *bearer; | 763 | struct tipc_bearer *bearer; |
| 728 | struct tipc_media *media; | 764 | struct tipc_media *media; |
| 765 | int len; | ||
| 729 | 766 | ||
| 730 | lc = (struct tipc_link_config *)TLV_DATA(msg->req); | 767 | lc = (struct tipc_link_config *)TLV_DATA(msg->req); |
| 731 | 768 | ||
| 769 | len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME); | ||
| 770 | if (!string_is_valid(lc->name, len)) | ||
| 771 | return -EINVAL; | ||
| 772 | |||
| 732 | media = tipc_media_find(lc->name); | 773 | media = tipc_media_find(lc->name); |
| 733 | if (media) { | 774 | if (media) { |
| 734 | cmd->doit = &__tipc_nl_media_set; | 775 | cmd->doit = &__tipc_nl_media_set; |
| @@ -750,6 +791,7 @@ static int tipc_nl_compat_link_reset_stats(struct tipc_nl_compat_cmd_doit *cmd, | |||
| 750 | { | 791 | { |
| 751 | char *name; | 792 | char *name; |
| 752 | struct nlattr *link; | 793 | struct nlattr *link; |
| 794 | int len; | ||
| 753 | 795 | ||
| 754 | name = (char *)TLV_DATA(msg->req); | 796 | name = (char *)TLV_DATA(msg->req); |
| 755 | 797 | ||
| @@ -757,6 +799,10 @@ static int tipc_nl_compat_link_reset_stats(struct tipc_nl_compat_cmd_doit *cmd, | |||
| 757 | if (!link) | 799 | if (!link) |
| 758 | return -EMSGSIZE; | 800 | return -EMSGSIZE; |
| 759 | 801 | ||
| 802 | len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME); | ||
| 803 | if (!string_is_valid(name, len)) | ||
| 804 | return -EINVAL; | ||
| 805 | |||
| 760 | if (nla_put_string(skb, TIPC_NLA_LINK_NAME, name)) | 806 | if (nla_put_string(skb, TIPC_NLA_LINK_NAME, name)) |
| 761 | return -EMSGSIZE; | 807 | return -EMSGSIZE; |
| 762 | 808 | ||
| @@ -778,6 +824,8 @@ static int tipc_nl_compat_name_table_dump_header(struct tipc_nl_compat_msg *msg) | |||
| 778 | }; | 824 | }; |
| 779 | 825 | ||
| 780 | ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req); | 826 | ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req); |
| 827 | if (TLV_GET_DATA_LEN(msg->req) < sizeof(struct tipc_name_table_query)) | ||
| 828 | return -EINVAL; | ||
| 781 | 829 | ||
| 782 | depth = ntohl(ntq->depth); | 830 | depth = ntohl(ntq->depth); |
| 783 | 831 | ||
| @@ -904,8 +952,10 @@ static int tipc_nl_compat_publ_dump(struct tipc_nl_compat_msg *msg, u32 sock) | |||
| 904 | 952 | ||
| 905 | hdr = genlmsg_put(args, 0, 0, &tipc_genl_family, NLM_F_MULTI, | 953 | hdr = genlmsg_put(args, 0, 0, &tipc_genl_family, NLM_F_MULTI, |
| 906 | TIPC_NL_PUBL_GET); | 954 | TIPC_NL_PUBL_GET); |
| 907 | if (!hdr) | 955 | if (!hdr) { |
| 956 | kfree_skb(args); | ||
| 908 | return -EMSGSIZE; | 957 | return -EMSGSIZE; |
| 958 | } | ||
| 909 | 959 | ||
| 910 | nest = nla_nest_start(args, TIPC_NLA_SOCK); | 960 | nest = nla_nest_start(args, TIPC_NLA_SOCK); |
| 911 | if (!nest) { | 961 | if (!nest) { |
| @@ -1206,7 +1256,7 @@ static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info) | |||
| 1206 | } | 1256 | } |
| 1207 | 1257 | ||
| 1208 | len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN); | 1258 | len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN); |
| 1209 | if (len && !TLV_OK(msg.req, len)) { | 1259 | if (!len || !TLV_OK(msg.req, len)) { |
| 1210 | msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED); | 1260 | msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED); |
| 1211 | err = -EOPNOTSUPP; | 1261 | err = -EOPNOTSUPP; |
| 1212 | goto send; | 1262 | goto send; |
diff --git a/net/tipc/node.c b/net/tipc/node.c index db2a6c3e0be9..2dc4919ab23c 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
| @@ -830,15 +830,16 @@ static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete) | |||
| 830 | tipc_node_write_lock(n); | 830 | tipc_node_write_lock(n); |
| 831 | if (!tipc_link_is_establishing(l)) { | 831 | if (!tipc_link_is_establishing(l)) { |
| 832 | __tipc_node_link_down(n, &bearer_id, &xmitq, &maddr); | 832 | __tipc_node_link_down(n, &bearer_id, &xmitq, &maddr); |
| 833 | if (delete) { | ||
| 834 | kfree(l); | ||
| 835 | le->link = NULL; | ||
| 836 | n->link_cnt--; | ||
| 837 | } | ||
| 838 | } else { | 833 | } else { |
| 839 | /* Defuse pending tipc_node_link_up() */ | 834 | /* Defuse pending tipc_node_link_up() */ |
| 835 | tipc_link_reset(l); | ||
| 840 | tipc_link_fsm_evt(l, LINK_RESET_EVT); | 836 | tipc_link_fsm_evt(l, LINK_RESET_EVT); |
| 841 | } | 837 | } |
| 838 | if (delete) { | ||
| 839 | kfree(l); | ||
| 840 | le->link = NULL; | ||
| 841 | n->link_cnt--; | ||
| 842 | } | ||
| 842 | trace_tipc_node_link_down(n, true, "node link down or deleted!"); | 843 | trace_tipc_node_link_down(n, true, "node link down or deleted!"); |
| 843 | tipc_node_write_unlock(n); | 844 | tipc_node_write_unlock(n); |
| 844 | if (delete) | 845 | if (delete) |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 1217c90a363b..684f2125fc6b 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
| @@ -388,7 +388,7 @@ static int tipc_sk_sock_err(struct socket *sock, long *timeout) | |||
| 388 | rc_ = tipc_sk_sock_err((sock_), timeo_); \ | 388 | rc_ = tipc_sk_sock_err((sock_), timeo_); \ |
| 389 | if (rc_) \ | 389 | if (rc_) \ |
| 390 | break; \ | 390 | break; \ |
| 391 | prepare_to_wait(sk_sleep(sk_), &wait_, TASK_INTERRUPTIBLE); \ | 391 | add_wait_queue(sk_sleep(sk_), &wait_); \ |
| 392 | release_sock(sk_); \ | 392 | release_sock(sk_); \ |
| 393 | *(timeo_) = wait_woken(&wait_, TASK_INTERRUPTIBLE, *(timeo_)); \ | 393 | *(timeo_) = wait_woken(&wait_, TASK_INTERRUPTIBLE, *(timeo_)); \ |
| 394 | sched_annotate_sleep(); \ | 394 | sched_annotate_sleep(); \ |
| @@ -1677,7 +1677,7 @@ static void tipc_sk_send_ack(struct tipc_sock *tsk) | |||
| 1677 | static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) | 1677 | static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) |
| 1678 | { | 1678 | { |
| 1679 | struct sock *sk = sock->sk; | 1679 | struct sock *sk = sock->sk; |
| 1680 | DEFINE_WAIT(wait); | 1680 | DEFINE_WAIT_FUNC(wait, woken_wake_function); |
| 1681 | long timeo = *timeop; | 1681 | long timeo = *timeop; |
| 1682 | int err = sock_error(sk); | 1682 | int err = sock_error(sk); |
| 1683 | 1683 | ||
| @@ -1685,15 +1685,17 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) | |||
| 1685 | return err; | 1685 | return err; |
| 1686 | 1686 | ||
| 1687 | for (;;) { | 1687 | for (;;) { |
| 1688 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | ||
| 1689 | if (timeo && skb_queue_empty(&sk->sk_receive_queue)) { | 1688 | if (timeo && skb_queue_empty(&sk->sk_receive_queue)) { |
| 1690 | if (sk->sk_shutdown & RCV_SHUTDOWN) { | 1689 | if (sk->sk_shutdown & RCV_SHUTDOWN) { |
| 1691 | err = -ENOTCONN; | 1690 | err = -ENOTCONN; |
| 1692 | break; | 1691 | break; |
| 1693 | } | 1692 | } |
| 1693 | add_wait_queue(sk_sleep(sk), &wait); | ||
| 1694 | release_sock(sk); | 1694 | release_sock(sk); |
| 1695 | timeo = schedule_timeout(timeo); | 1695 | timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo); |
| 1696 | sched_annotate_sleep(); | ||
| 1696 | lock_sock(sk); | 1697 | lock_sock(sk); |
| 1698 | remove_wait_queue(sk_sleep(sk), &wait); | ||
| 1697 | } | 1699 | } |
| 1698 | err = 0; | 1700 | err = 0; |
| 1699 | if (!skb_queue_empty(&sk->sk_receive_queue)) | 1701 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
| @@ -1709,7 +1711,6 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) | |||
| 1709 | if (err) | 1711 | if (err) |
| 1710 | break; | 1712 | break; |
| 1711 | } | 1713 | } |
| 1712 | finish_wait(sk_sleep(sk), &wait); | ||
| 1713 | *timeop = timeo; | 1714 | *timeop = timeo; |
| 1714 | return err; | 1715 | return err; |
| 1715 | } | 1716 | } |
diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c index efb16f69bd2c..a457c0fbbef1 100644 --- a/net/tipc/topsrv.c +++ b/net/tipc/topsrv.c | |||
| @@ -398,7 +398,7 @@ static int tipc_conn_rcv_from_sock(struct tipc_conn *con) | |||
| 398 | ret = sock_recvmsg(con->sock, &msg, MSG_DONTWAIT); | 398 | ret = sock_recvmsg(con->sock, &msg, MSG_DONTWAIT); |
| 399 | if (ret == -EWOULDBLOCK) | 399 | if (ret == -EWOULDBLOCK) |
| 400 | return -EWOULDBLOCK; | 400 | return -EWOULDBLOCK; |
| 401 | if (ret > 0) { | 401 | if (ret == sizeof(s)) { |
| 402 | read_lock_bh(&sk->sk_callback_lock); | 402 | read_lock_bh(&sk->sk_callback_lock); |
| 403 | ret = tipc_conn_rcv_sub(srv, con, &s); | 403 | ret = tipc_conn_rcv_sub(srv, con, &s); |
| 404 | read_unlock_bh(&sk->sk_callback_lock); | 404 | read_unlock_bh(&sk->sk_callback_lock); |
