diff options
author | David S. Miller <davem@davemloft.net> | 2019-01-15 23:29:21 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-01-15 23:29:21 -0500 |
commit | 70a44f9f6e4297e013de29088608ab2c6fb642f7 (patch) | |
tree | 524c8a581800f8fe54c5006fac5b1f52505c567a | |
parent | d62f38c295e56147e8298af1e0e0ec9e7cc14937 (diff) | |
parent | 2753ca5d9009c180dbfd4c802c80983b4b6108d1 (diff) |
Merge branch 'tipc-uninit-values'
Ying Xue says:
====================
tipc: fix uninit-value issues reported by syzbot
Recently, syzbot complained that TIPC module exits several issues
associated with uninit-value type. So, in this series, we try to
fix them as many as possible.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/tipc/netlink_compat.c | 50 | ||||
-rw-r--r-- | net/tipc/topsrv.c | 2 |
2 files changed, 50 insertions, 2 deletions
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 77e4b2418f30..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 | ||
@@ -1208,7 +1256,7 @@ static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info) | |||
1208 | } | 1256 | } |
1209 | 1257 | ||
1210 | len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN); | 1258 | len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN); |
1211 | if (len && !TLV_OK(msg.req, len)) { | 1259 | if (!len || !TLV_OK(msg.req, len)) { |
1212 | msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED); | 1260 | msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED); |
1213 | err = -EOPNOTSUPP; | 1261 | err = -EOPNOTSUPP; |
1214 | goto send; | 1262 | goto send; |
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); |