Commit 70a44f9f authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents d62f38c2 2753ca5d
...@@ -87,6 +87,11 @@ static int tipc_skb_tailroom(struct sk_buff *skb) ...@@ -87,6 +87,11 @@ static int tipc_skb_tailroom(struct sk_buff *skb)
return limit; return limit;
} }
static inline int TLV_GET_DATA_LEN(struct tlv_desc *tlv)
{
return TLV_GET_LEN(tlv) - TLV_SPACE(0);
}
static int tipc_add_tlv(struct sk_buff *skb, u16 type, void *data, u16 len) static int tipc_add_tlv(struct sk_buff *skb, u16 type, void *data, u16 len)
{ {
struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(skb); 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,6 +171,11 @@ static struct sk_buff *tipc_get_err_tlv(char *str)
return buf; return buf;
} }
static inline bool string_is_valid(char *s, int len)
{
return memchr(s, '\0', len) ? true : false;
}
static int __tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, static int __tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd,
struct tipc_nl_compat_msg *msg, struct tipc_nl_compat_msg *msg,
struct sk_buff *arg) struct sk_buff *arg)
...@@ -379,6 +389,7 @@ static int tipc_nl_compat_bearer_enable(struct tipc_nl_compat_cmd_doit *cmd, ...@@ -379,6 +389,7 @@ static int tipc_nl_compat_bearer_enable(struct tipc_nl_compat_cmd_doit *cmd,
struct nlattr *prop; struct nlattr *prop;
struct nlattr *bearer; struct nlattr *bearer;
struct tipc_bearer_config *b; struct tipc_bearer_config *b;
int len;
b = (struct tipc_bearer_config *)TLV_DATA(msg->req); b = (struct tipc_bearer_config *)TLV_DATA(msg->req);
...@@ -386,6 +397,10 @@ static int tipc_nl_compat_bearer_enable(struct tipc_nl_compat_cmd_doit *cmd, ...@@ -386,6 +397,10 @@ static int tipc_nl_compat_bearer_enable(struct tipc_nl_compat_cmd_doit *cmd,
if (!bearer) if (!bearer)
return -EMSGSIZE; return -EMSGSIZE;
len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_BEARER_NAME);
if (!string_is_valid(b->name, len))
return -EINVAL;
if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, b->name)) if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, b->name))
return -EMSGSIZE; return -EMSGSIZE;
...@@ -411,6 +426,7 @@ static int tipc_nl_compat_bearer_disable(struct tipc_nl_compat_cmd_doit *cmd, ...@@ -411,6 +426,7 @@ static int tipc_nl_compat_bearer_disable(struct tipc_nl_compat_cmd_doit *cmd,
{ {
char *name; char *name;
struct nlattr *bearer; struct nlattr *bearer;
int len;
name = (char *)TLV_DATA(msg->req); name = (char *)TLV_DATA(msg->req);
...@@ -418,6 +434,10 @@ static int tipc_nl_compat_bearer_disable(struct tipc_nl_compat_cmd_doit *cmd, ...@@ -418,6 +434,10 @@ static int tipc_nl_compat_bearer_disable(struct tipc_nl_compat_cmd_doit *cmd,
if (!bearer) if (!bearer)
return -EMSGSIZE; return -EMSGSIZE;
len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_BEARER_NAME);
if (!string_is_valid(name, len))
return -EINVAL;
if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, name)) if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, name))
return -EMSGSIZE; return -EMSGSIZE;
...@@ -478,6 +498,7 @@ static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg, ...@@ -478,6 +498,7 @@ static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg,
struct nlattr *prop[TIPC_NLA_PROP_MAX + 1]; struct nlattr *prop[TIPC_NLA_PROP_MAX + 1];
struct nlattr *stats[TIPC_NLA_STATS_MAX + 1]; struct nlattr *stats[TIPC_NLA_STATS_MAX + 1];
int err; int err;
int len;
if (!attrs[TIPC_NLA_LINK]) if (!attrs[TIPC_NLA_LINK])
return -EINVAL; return -EINVAL;
...@@ -504,6 +525,11 @@ static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg, ...@@ -504,6 +525,11 @@ static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg,
return err; return err;
name = (char *)TLV_DATA(msg->req); name = (char *)TLV_DATA(msg->req);
len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME);
if (!string_is_valid(name, len))
return -EINVAL;
if (strcmp(name, nla_data(link[TIPC_NLA_LINK_NAME])) != 0) if (strcmp(name, nla_data(link[TIPC_NLA_LINK_NAME])) != 0)
return 0; return 0;
...@@ -644,6 +670,7 @@ static int tipc_nl_compat_media_set(struct sk_buff *skb, ...@@ -644,6 +670,7 @@ static int tipc_nl_compat_media_set(struct sk_buff *skb,
struct nlattr *prop; struct nlattr *prop;
struct nlattr *media; struct nlattr *media;
struct tipc_link_config *lc; struct tipc_link_config *lc;
int len;
lc = (struct tipc_link_config *)TLV_DATA(msg->req); lc = (struct tipc_link_config *)TLV_DATA(msg->req);
...@@ -651,6 +678,10 @@ static int tipc_nl_compat_media_set(struct sk_buff *skb, ...@@ -651,6 +678,10 @@ static int tipc_nl_compat_media_set(struct sk_buff *skb,
if (!media) if (!media)
return -EMSGSIZE; return -EMSGSIZE;
len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_MEDIA_NAME);
if (!string_is_valid(lc->name, len))
return -EINVAL;
if (nla_put_string(skb, TIPC_NLA_MEDIA_NAME, lc->name)) if (nla_put_string(skb, TIPC_NLA_MEDIA_NAME, lc->name))
return -EMSGSIZE; return -EMSGSIZE;
...@@ -671,6 +702,7 @@ static int tipc_nl_compat_bearer_set(struct sk_buff *skb, ...@@ -671,6 +702,7 @@ static int tipc_nl_compat_bearer_set(struct sk_buff *skb,
struct nlattr *prop; struct nlattr *prop;
struct nlattr *bearer; struct nlattr *bearer;
struct tipc_link_config *lc; struct tipc_link_config *lc;
int len;
lc = (struct tipc_link_config *)TLV_DATA(msg->req); lc = (struct tipc_link_config *)TLV_DATA(msg->req);
...@@ -678,6 +710,10 @@ static int tipc_nl_compat_bearer_set(struct sk_buff *skb, ...@@ -678,6 +710,10 @@ static int tipc_nl_compat_bearer_set(struct sk_buff *skb,
if (!bearer) if (!bearer)
return -EMSGSIZE; return -EMSGSIZE;
len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_MEDIA_NAME);
if (!string_is_valid(lc->name, len))
return -EINVAL;
if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, lc->name)) if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, lc->name))
return -EMSGSIZE; return -EMSGSIZE;
...@@ -726,9 +762,14 @@ static int tipc_nl_compat_link_set(struct tipc_nl_compat_cmd_doit *cmd, ...@@ -726,9 +762,14 @@ static int tipc_nl_compat_link_set(struct tipc_nl_compat_cmd_doit *cmd,
struct tipc_link_config *lc; struct tipc_link_config *lc;
struct tipc_bearer *bearer; struct tipc_bearer *bearer;
struct tipc_media *media; struct tipc_media *media;
int len;
lc = (struct tipc_link_config *)TLV_DATA(msg->req); lc = (struct tipc_link_config *)TLV_DATA(msg->req);
len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME);
if (!string_is_valid(lc->name, len))
return -EINVAL;
media = tipc_media_find(lc->name); media = tipc_media_find(lc->name);
if (media) { if (media) {
cmd->doit = &__tipc_nl_media_set; 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,6 +791,7 @@ static int tipc_nl_compat_link_reset_stats(struct tipc_nl_compat_cmd_doit *cmd,
{ {
char *name; char *name;
struct nlattr *link; struct nlattr *link;
int len;
name = (char *)TLV_DATA(msg->req); name = (char *)TLV_DATA(msg->req);
...@@ -757,6 +799,10 @@ static int tipc_nl_compat_link_reset_stats(struct tipc_nl_compat_cmd_doit *cmd, ...@@ -757,6 +799,10 @@ static int tipc_nl_compat_link_reset_stats(struct tipc_nl_compat_cmd_doit *cmd,
if (!link) if (!link)
return -EMSGSIZE; return -EMSGSIZE;
len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME);
if (!string_is_valid(name, len))
return -EINVAL;
if (nla_put_string(skb, TIPC_NLA_LINK_NAME, name)) if (nla_put_string(skb, TIPC_NLA_LINK_NAME, name))
return -EMSGSIZE; return -EMSGSIZE;
...@@ -778,6 +824,8 @@ static int tipc_nl_compat_name_table_dump_header(struct tipc_nl_compat_msg *msg) ...@@ -778,6 +824,8 @@ static int tipc_nl_compat_name_table_dump_header(struct tipc_nl_compat_msg *msg)
}; };
ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req); ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req);
if (TLV_GET_DATA_LEN(msg->req) < sizeof(struct tipc_name_table_query))
return -EINVAL;
depth = ntohl(ntq->depth); depth = ntohl(ntq->depth);
...@@ -1208,7 +1256,7 @@ static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info) ...@@ -1208,7 +1256,7 @@ static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info)
} }
len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN); len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN);
if (len && !TLV_OK(msg.req, len)) { if (!len || !TLV_OK(msg.req, len)) {
msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED); msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED);
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto send; goto send;
......
...@@ -398,7 +398,7 @@ static int tipc_conn_rcv_from_sock(struct tipc_conn *con) ...@@ -398,7 +398,7 @@ static int tipc_conn_rcv_from_sock(struct tipc_conn *con)
ret = sock_recvmsg(con->sock, &msg, MSG_DONTWAIT); ret = sock_recvmsg(con->sock, &msg, MSG_DONTWAIT);
if (ret == -EWOULDBLOCK) if (ret == -EWOULDBLOCK)
return -EWOULDBLOCK; return -EWOULDBLOCK;
if (ret > 0) { if (ret == sizeof(s)) {
read_lock_bh(&sk->sk_callback_lock); read_lock_bh(&sk->sk_callback_lock);
ret = tipc_conn_rcv_sub(srv, con, &s); ret = tipc_conn_rcv_sub(srv, con, &s);
read_unlock_bh(&sk->sk_callback_lock); read_unlock_bh(&sk->sk_callback_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment