diff options
| author | James Morris <james.l.morris@oracle.com> | 2017-11-29 12:47:41 +1100 | 
|---|---|---|
| committer | James Morris <james.l.morris@oracle.com> | 2017-11-29 12:47:41 +1100 | 
| commit | cf40a76e7d5874bb25f4404eecc58a2e033af885 (patch) | |
| tree | 8fd81cbea03c87b3d41d7ae5b1d11eadd35d6ef5 /net/ipv4/inet_diag.c | |
| parent | ab5348c9c23cd253f5902980d2d8fe067dc24c82 (diff) | |
| parent | 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323 (diff) | |
Merge tag 'v4.15-rc1' into next-seccomp
Linux 4.15-rc1
Diffstat (limited to 'net/ipv4/inet_diag.c')
| -rw-r--r-- | net/ipv4/inet_diag.c | 33 | 
1 files changed, 29 insertions, 4 deletions
| diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 3828b3a805cd..c9c35b61a027 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -93,8 +93,17 @@ void inet_diag_msg_common_fill(struct inet_diag_msg *r, struct sock *sk)  }  EXPORT_SYMBOL_GPL(inet_diag_msg_common_fill); -static size_t inet_sk_attr_size(void) +static size_t inet_sk_attr_size(struct sock *sk, +				const struct inet_diag_req_v2 *req, +				bool net_admin)  { +	const struct inet_diag_handler *handler; +	size_t aux = 0; + +	handler = inet_diag_table[req->sdiag_protocol]; +	if (handler && handler->idiag_get_aux_size) +		aux = handler->idiag_get_aux_size(sk, net_admin); +  	return	  nla_total_size(sizeof(struct tcp_info))  		+ nla_total_size(1) /* INET_DIAG_SHUTDOWN */  		+ nla_total_size(1) /* INET_DIAG_TOS */ @@ -105,6 +114,7 @@ static size_t inet_sk_attr_size(void)  		+ nla_total_size(SK_MEMINFO_VARS * sizeof(u32))  		+ nla_total_size(TCP_CA_NAME_MAX)  		+ nla_total_size(sizeof(struct tcpvegas_info)) +		+ aux  		+ 64;  } @@ -260,6 +270,10 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,  	handler->idiag_get_info(sk, r, info); +	if (ext & (1 << (INET_DIAG_INFO - 1)) && handler->idiag_get_aux) +		if (handler->idiag_get_aux(sk, net_admin, skb) < 0) +			goto errout; +  	if (sk->sk_state < TCP_TIME_WAIT) {  		union tcp_cc_info info;  		size_t sz = 0; @@ -274,6 +288,17 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,  			goto errout;  	} +	if (ext & (1 << (INET_DIAG_CLASS_ID - 1))) { +		u32 classid = 0; + +#ifdef CONFIG_SOCK_CGROUP_DATA +		classid = sock_cgroup_classid(&sk->sk_cgrp_data); +#endif + +		if (nla_put_u32(skb, INET_DIAG_CLASS_ID, classid)) +			goto errout; +	} +  out:  	nlmsg_end(skb, nlh);  	return 0; @@ -438,6 +463,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo,  			    const struct nlmsghdr *nlh,  			    const struct inet_diag_req_v2 *req)  { +	bool net_admin = netlink_net_capable(in_skb, CAP_NET_ADMIN);  	struct net *net = sock_net(in_skb->sk);  	struct sk_buff *rep;  	struct sock *sk; @@ -447,7 +473,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo,  	if (IS_ERR(sk))  		return PTR_ERR(sk); -	rep = nlmsg_new(inet_sk_attr_size(), GFP_KERNEL); +	rep = nlmsg_new(inet_sk_attr_size(sk, req, net_admin), GFP_KERNEL);  	if (!rep) {  		err = -ENOMEM;  		goto out; @@ -456,8 +482,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo,  	err = sk_diag_fill(sk, rep, req,  			   sk_user_ns(NETLINK_CB(in_skb).sk),  			   NETLINK_CB(in_skb).portid, -			   nlh->nlmsg_seq, 0, nlh, -			   netlink_net_capable(in_skb, CAP_NET_ADMIN)); +			   nlh->nlmsg_seq, 0, nlh, net_admin);  	if (err < 0) {  		WARN_ON(err == -EMSGSIZE);  		nlmsg_free(rep); | 
