Commit bb4d37c8 authored by Eric Dumazet's avatar Eric Dumazet Committed by Kamal Mostafa

inet_diag: fix possible overflow in inet_diag_dump_one_icsk()

[ Upstream commit c8e2c80d ]

inet_diag_dump_one_icsk() allocates too small skb.

Add inet_sk_attr_size() helper right before inet_sk_diag_fill()
so that it can be updated if/when new attributes are added.

iproute2/ss currently does not use this dump_one() interface,
this might explain nobody noticed this problem yet.
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarKamal Mostafa <kamal@canonical.com>
parent 744ff700
...@@ -71,6 +71,20 @@ static inline void inet_diag_unlock_handler( ...@@ -71,6 +71,20 @@ static inline void inet_diag_unlock_handler(
mutex_unlock(&inet_diag_table_mutex); mutex_unlock(&inet_diag_table_mutex);
} }
static size_t inet_sk_attr_size(void)
{
return nla_total_size(sizeof(struct tcp_info))
+ nla_total_size(1) /* INET_DIAG_SHUTDOWN */
+ nla_total_size(1) /* INET_DIAG_TOS */
+ nla_total_size(1) /* INET_DIAG_TCLASS */
+ nla_total_size(sizeof(struct inet_diag_meminfo))
+ nla_total_size(sizeof(struct inet_diag_msg))
+ nla_total_size(SK_MEMINFO_VARS * sizeof(u32))
+ nla_total_size(TCP_CA_NAME_MAX)
+ nla_total_size(sizeof(struct tcpvegas_info))
+ 64;
}
int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
struct sk_buff *skb, struct inet_diag_req_v2 *req, struct sk_buff *skb, struct inet_diag_req_v2 *req,
struct user_namespace *user_ns, struct user_namespace *user_ns,
...@@ -324,9 +338,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s ...@@ -324,9 +338,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s
if (err) if (err)
goto out; goto out;
rep = nlmsg_new(sizeof(struct inet_diag_msg) + rep = nlmsg_new(inet_sk_attr_size(), GFP_KERNEL);
sizeof(struct inet_diag_meminfo) +
sizeof(struct tcp_info) + 64, GFP_KERNEL);
if (!rep) { if (!rep) {
err = -ENOMEM; err = -ENOMEM;
goto out; goto out;
......
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