root/net/core/sock_diag.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sock_gen_cookie
  2. sock_diag_check_cookie
  3. sock_diag_save_cookie
  4. sock_diag_put_meminfo
  5. sock_diag_put_filterinfo
  6. sock_diag_nlmsg_size
  7. sock_diag_broadcast_destroy_work
  8. sock_diag_broadcast_destroy
  9. sock_diag_register_inet_compat
  10. sock_diag_unregister_inet_compat
  11. sock_diag_register
  12. sock_diag_unregister
  13. __sock_diag_cmd
  14. sock_diag_rcv_msg
  15. sock_diag_rcv
  16. sock_diag_bind
  17. sock_diag_destroy
  18. diag_net_init
  19. diag_net_exit
  20. sock_diag_init

   1 /* License: GPL */
   2 
   3 #include <linux/mutex.h>
   4 #include <linux/socket.h>
   5 #include <linux/skbuff.h>
   6 #include <net/netlink.h>
   7 #include <net/net_namespace.h>
   8 #include <linux/module.h>
   9 #include <net/sock.h>
  10 #include <linux/kernel.h>
  11 #include <linux/tcp.h>
  12 #include <linux/workqueue.h>
  13 #include <linux/nospec.h>
  14 
  15 #include <linux/inet_diag.h>
  16 #include <linux/sock_diag.h>
  17 
  18 static const struct sock_diag_handler *sock_diag_handlers[AF_MAX];
  19 static int (*inet_rcv_compat)(struct sk_buff *skb, struct nlmsghdr *nlh);
  20 static DEFINE_MUTEX(sock_diag_table_mutex);
  21 static struct workqueue_struct *broadcast_wq;
  22 static atomic64_t cookie_gen;
  23 
  24 u64 sock_gen_cookie(struct sock *sk)
  25 {
  26         while (1) {
  27                 u64 res = atomic64_read(&sk->sk_cookie);
  28 
  29                 if (res)
  30                         return res;
  31                 res = atomic64_inc_return(&cookie_gen);
  32                 atomic64_cmpxchg(&sk->sk_cookie, 0, res);
  33         }
  34 }
  35 
  36 int sock_diag_check_cookie(struct sock *sk, const __u32 *cookie)
  37 {
  38         u64 res;
  39 
  40         if (cookie[0] == INET_DIAG_NOCOOKIE && cookie[1] == INET_DIAG_NOCOOKIE)
  41                 return 0;
  42 
  43         res = sock_gen_cookie(sk);
  44         if ((u32)res != cookie[0] || (u32)(res >> 32) != cookie[1])
  45                 return -ESTALE;
  46 
  47         return 0;
  48 }
  49 EXPORT_SYMBOL_GPL(sock_diag_check_cookie);
  50 
  51 void sock_diag_save_cookie(struct sock *sk, __u32 *cookie)
  52 {
  53         u64 res = sock_gen_cookie(sk);
  54 
  55         cookie[0] = (u32)res;
  56         cookie[1] = (u32)(res >> 32);
  57 }
  58 EXPORT_SYMBOL_GPL(sock_diag_save_cookie);
  59 
  60 int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attrtype)
  61 {
  62         u32 mem[SK_MEMINFO_VARS];
  63 
  64         sk_get_meminfo(sk, mem);
  65 
  66         return nla_put(skb, attrtype, sizeof(mem), &mem);
  67 }
  68 EXPORT_SYMBOL_GPL(sock_diag_put_meminfo);
  69 
  70 int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk,
  71                              struct sk_buff *skb, int attrtype)
  72 {
  73         struct sock_fprog_kern *fprog;
  74         struct sk_filter *filter;
  75         struct nlattr *attr;
  76         unsigned int flen;
  77         int err = 0;
  78 
  79         if (!may_report_filterinfo) {
  80                 nla_reserve(skb, attrtype, 0);
  81                 return 0;
  82         }
  83 
  84         rcu_read_lock();
  85         filter = rcu_dereference(sk->sk_filter);
  86         if (!filter)
  87                 goto out;
  88 
  89         fprog = filter->prog->orig_prog;
  90         if (!fprog)
  91                 goto out;
  92 
  93         flen = bpf_classic_proglen(fprog);
  94 
  95         attr = nla_reserve(skb, attrtype, flen);
  96         if (attr == NULL) {
  97                 err = -EMSGSIZE;
  98                 goto out;
  99         }
 100 
 101         memcpy(nla_data(attr), fprog->filter, flen);
 102 out:
 103         rcu_read_unlock();
 104         return err;
 105 }
 106 EXPORT_SYMBOL(sock_diag_put_filterinfo);
 107 
 108 struct broadcast_sk {
 109         struct sock *sk;
 110         struct work_struct work;
 111 };
 112 
 113 static size_t sock_diag_nlmsg_size(void)
 114 {
 115         return NLMSG_ALIGN(sizeof(struct inet_diag_msg)
 116                + nla_total_size(sizeof(u8)) /* INET_DIAG_PROTOCOL */
 117                + nla_total_size_64bit(sizeof(struct tcp_info))); /* INET_DIAG_INFO */
 118 }
 119 
 120 static void sock_diag_broadcast_destroy_work(struct work_struct *work)
 121 {
 122         struct broadcast_sk *bsk =
 123                 container_of(work, struct broadcast_sk, work);
 124         struct sock *sk = bsk->sk;
 125         const struct sock_diag_handler *hndl;
 126         struct sk_buff *skb;
 127         const enum sknetlink_groups group = sock_diag_destroy_group(sk);
 128         int err = -1;
 129 
 130         WARN_ON(group == SKNLGRP_NONE);
 131 
 132         skb = nlmsg_new(sock_diag_nlmsg_size(), GFP_KERNEL);
 133         if (!skb)
 134                 goto out;
 135 
 136         mutex_lock(&sock_diag_table_mutex);
 137         hndl = sock_diag_handlers[sk->sk_family];
 138         if (hndl && hndl->get_info)
 139                 err = hndl->get_info(skb, sk);
 140         mutex_unlock(&sock_diag_table_mutex);
 141 
 142         if (!err)
 143                 nlmsg_multicast(sock_net(sk)->diag_nlsk, skb, 0, group,
 144                                 GFP_KERNEL);
 145         else
 146                 kfree_skb(skb);
 147 out:
 148         sk_destruct(sk);
 149         kfree(bsk);
 150 }
 151 
 152 void sock_diag_broadcast_destroy(struct sock *sk)
 153 {
 154         /* Note, this function is often called from an interrupt context. */
 155         struct broadcast_sk *bsk =
 156                 kmalloc(sizeof(struct broadcast_sk), GFP_ATOMIC);
 157         if (!bsk)
 158                 return sk_destruct(sk);
 159         bsk->sk = sk;
 160         INIT_WORK(&bsk->work, sock_diag_broadcast_destroy_work);
 161         queue_work(broadcast_wq, &bsk->work);
 162 }
 163 
 164 void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh))
 165 {
 166         mutex_lock(&sock_diag_table_mutex);
 167         inet_rcv_compat = fn;
 168         mutex_unlock(&sock_diag_table_mutex);
 169 }
 170 EXPORT_SYMBOL_GPL(sock_diag_register_inet_compat);
 171 
 172 void sock_diag_unregister_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh))
 173 {
 174         mutex_lock(&sock_diag_table_mutex);
 175         inet_rcv_compat = NULL;
 176         mutex_unlock(&sock_diag_table_mutex);
 177 }
 178 EXPORT_SYMBOL_GPL(sock_diag_unregister_inet_compat);
 179 
 180 int sock_diag_register(const struct sock_diag_handler *hndl)
 181 {
 182         int err = 0;
 183 
 184         if (hndl->family >= AF_MAX)
 185                 return -EINVAL;
 186 
 187         mutex_lock(&sock_diag_table_mutex);
 188         if (sock_diag_handlers[hndl->family])
 189                 err = -EBUSY;
 190         else
 191                 sock_diag_handlers[hndl->family] = hndl;
 192         mutex_unlock(&sock_diag_table_mutex);
 193 
 194         return err;
 195 }
 196 EXPORT_SYMBOL_GPL(sock_diag_register);
 197 
 198 void sock_diag_unregister(const struct sock_diag_handler *hnld)
 199 {
 200         int family = hnld->family;
 201 
 202         if (family >= AF_MAX)
 203                 return;
 204 
 205         mutex_lock(&sock_diag_table_mutex);
 206         BUG_ON(sock_diag_handlers[family] != hnld);
 207         sock_diag_handlers[family] = NULL;
 208         mutex_unlock(&sock_diag_table_mutex);
 209 }
 210 EXPORT_SYMBOL_GPL(sock_diag_unregister);
 211 
 212 static int __sock_diag_cmd(struct sk_buff *skb, struct nlmsghdr *nlh)
 213 {
 214         int err;
 215         struct sock_diag_req *req = nlmsg_data(nlh);
 216         const struct sock_diag_handler *hndl;
 217 
 218         if (nlmsg_len(nlh) < sizeof(*req))
 219                 return -EINVAL;
 220 
 221         if (req->sdiag_family >= AF_MAX)
 222                 return -EINVAL;
 223         req->sdiag_family = array_index_nospec(req->sdiag_family, AF_MAX);
 224 
 225         if (sock_diag_handlers[req->sdiag_family] == NULL)
 226                 sock_load_diag_module(req->sdiag_family, 0);
 227 
 228         mutex_lock(&sock_diag_table_mutex);
 229         hndl = sock_diag_handlers[req->sdiag_family];
 230         if (hndl == NULL)
 231                 err = -ENOENT;
 232         else if (nlh->nlmsg_type == SOCK_DIAG_BY_FAMILY)
 233                 err = hndl->dump(skb, nlh);
 234         else if (nlh->nlmsg_type == SOCK_DESTROY && hndl->destroy)
 235                 err = hndl->destroy(skb, nlh);
 236         else
 237                 err = -EOPNOTSUPP;
 238         mutex_unlock(&sock_diag_table_mutex);
 239 
 240         return err;
 241 }
 242 
 243 static int sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
 244                              struct netlink_ext_ack *extack)
 245 {
 246         int ret;
 247 
 248         switch (nlh->nlmsg_type) {
 249         case TCPDIAG_GETSOCK:
 250         case DCCPDIAG_GETSOCK:
 251                 if (inet_rcv_compat == NULL)
 252                         sock_load_diag_module(AF_INET, 0);
 253 
 254                 mutex_lock(&sock_diag_table_mutex);
 255                 if (inet_rcv_compat != NULL)
 256                         ret = inet_rcv_compat(skb, nlh);
 257                 else
 258                         ret = -EOPNOTSUPP;
 259                 mutex_unlock(&sock_diag_table_mutex);
 260 
 261                 return ret;
 262         case SOCK_DIAG_BY_FAMILY:
 263         case SOCK_DESTROY:
 264                 return __sock_diag_cmd(skb, nlh);
 265         default:
 266                 return -EINVAL;
 267         }
 268 }
 269 
 270 static DEFINE_MUTEX(sock_diag_mutex);
 271 
 272 static void sock_diag_rcv(struct sk_buff *skb)
 273 {
 274         mutex_lock(&sock_diag_mutex);
 275         netlink_rcv_skb(skb, &sock_diag_rcv_msg);
 276         mutex_unlock(&sock_diag_mutex);
 277 }
 278 
 279 static int sock_diag_bind(struct net *net, int group)
 280 {
 281         switch (group) {
 282         case SKNLGRP_INET_TCP_DESTROY:
 283         case SKNLGRP_INET_UDP_DESTROY:
 284                 if (!sock_diag_handlers[AF_INET])
 285                         sock_load_diag_module(AF_INET, 0);
 286                 break;
 287         case SKNLGRP_INET6_TCP_DESTROY:
 288         case SKNLGRP_INET6_UDP_DESTROY:
 289                 if (!sock_diag_handlers[AF_INET6])
 290                         sock_load_diag_module(AF_INET6, 0);
 291                 break;
 292         }
 293         return 0;
 294 }
 295 
 296 int sock_diag_destroy(struct sock *sk, int err)
 297 {
 298         if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
 299                 return -EPERM;
 300 
 301         if (!sk->sk_prot->diag_destroy)
 302                 return -EOPNOTSUPP;
 303 
 304         return sk->sk_prot->diag_destroy(sk, err);
 305 }
 306 EXPORT_SYMBOL_GPL(sock_diag_destroy);
 307 
 308 static int __net_init diag_net_init(struct net *net)
 309 {
 310         struct netlink_kernel_cfg cfg = {
 311                 .groups = SKNLGRP_MAX,
 312                 .input  = sock_diag_rcv,
 313                 .bind   = sock_diag_bind,
 314                 .flags  = NL_CFG_F_NONROOT_RECV,
 315         };
 316 
 317         net->diag_nlsk = netlink_kernel_create(net, NETLINK_SOCK_DIAG, &cfg);
 318         return net->diag_nlsk == NULL ? -ENOMEM : 0;
 319 }
 320 
 321 static void __net_exit diag_net_exit(struct net *net)
 322 {
 323         netlink_kernel_release(net->diag_nlsk);
 324         net->diag_nlsk = NULL;
 325 }
 326 
 327 static struct pernet_operations diag_net_ops = {
 328         .init = diag_net_init,
 329         .exit = diag_net_exit,
 330 };
 331 
 332 static int __init sock_diag_init(void)
 333 {
 334         broadcast_wq = alloc_workqueue("sock_diag_events", 0, 0);
 335         BUG_ON(!broadcast_wq);
 336         return register_pernet_subsys(&diag_net_ops);
 337 }
 338 device_initcall(sock_diag_init);

/* [<][>][^][v][top][bottom][index][help] */