linux/net/ipv4/inet_diag.c
<<
>>
Prefs
   1/*
   2 * inet_diag.c  Module for monitoring INET transport protocols sockets.
   3 *
   4 * Authors:     Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
   5 *
   6 *      This program is free software; you can redistribute it and/or
   7 *      modify it under the terms of the GNU General Public License
   8 *      as published by the Free Software Foundation; either version
   9 *      2 of the License, or (at your option) any later version.
  10 */
  11
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/types.h>
  15#include <linux/fcntl.h>
  16#include <linux/random.h>
  17#include <linux/slab.h>
  18#include <linux/cache.h>
  19#include <linux/init.h>
  20#include <linux/time.h>
  21
  22#include <net/icmp.h>
  23#include <net/tcp.h>
  24#include <net/ipv6.h>
  25#include <net/inet_common.h>
  26#include <net/inet_connection_sock.h>
  27#include <net/inet_hashtables.h>
  28#include <net/inet_timewait_sock.h>
  29#include <net/inet6_hashtables.h>
  30#include <net/netlink.h>
  31
  32#include <linux/inet.h>
  33#include <linux/stddef.h>
  34
  35#include <linux/inet_diag.h>
  36#include <linux/sock_diag.h>
  37
  38static const struct inet_diag_handler **inet_diag_table;
  39
  40struct inet_diag_entry {
  41        __be32 *saddr;
  42        __be32 *daddr;
  43        u16 sport;
  44        u16 dport;
  45        u16 family;
  46        u16 userlocks;
  47#if IS_ENABLED(CONFIG_IPV6)
  48        struct in6_addr saddr_storage;  /* for IPv4-mapped-IPv6 addresses */
  49        struct in6_addr daddr_storage;  /* for IPv4-mapped-IPv6 addresses */
  50#endif
  51};
  52
  53static DEFINE_MUTEX(inet_diag_table_mutex);
  54
  55static const struct inet_diag_handler *inet_diag_lock_handler(int proto)
  56{
  57        if (!inet_diag_table[proto])
  58                request_module("net-pf-%d-proto-%d-type-%d-%d", PF_NETLINK,
  59                               NETLINK_SOCK_DIAG, AF_INET, proto);
  60
  61        mutex_lock(&inet_diag_table_mutex);
  62        if (!inet_diag_table[proto])
  63                return ERR_PTR(-ENOENT);
  64
  65        return inet_diag_table[proto];
  66}
  67
  68static inline void inet_diag_unlock_handler(
  69        const struct inet_diag_handler *handler)
  70{
  71        mutex_unlock(&inet_diag_table_mutex);
  72}
  73
  74int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
  75                              struct sk_buff *skb, struct inet_diag_req_v2 *req,
  76                              struct user_namespace *user_ns,                   
  77                              u32 portid, u32 seq, u16 nlmsg_flags,
  78                              const struct nlmsghdr *unlh)
  79{
  80        const struct inet_sock *inet = inet_sk(sk);
  81        struct inet_diag_msg *r;
  82        struct nlmsghdr  *nlh;
  83        struct nlattr *attr;
  84        void *info = NULL;
  85        const struct inet_diag_handler *handler;
  86        int ext = req->idiag_ext;
  87
  88        handler = inet_diag_table[req->sdiag_protocol];
  89        BUG_ON(handler == NULL);
  90
  91        nlh = nlmsg_put(skb, portid, seq, unlh->nlmsg_type, sizeof(*r),
  92                        nlmsg_flags);
  93        if (!nlh)
  94                return -EMSGSIZE;
  95
  96        r = nlmsg_data(nlh);
  97        BUG_ON(sk->sk_state == TCP_TIME_WAIT);
  98
  99        r->idiag_family = sk->sk_family;
 100        r->idiag_state = sk->sk_state;
 101        r->idiag_timer = 0;
 102        r->idiag_retrans = 0;
 103
 104        r->id.idiag_if = sk->sk_bound_dev_if;
 105        sock_diag_save_cookie(sk, r->id.idiag_cookie);
 106
 107        r->id.idiag_sport = inet->inet_sport;
 108        r->id.idiag_dport = inet->inet_dport;
 109        r->id.idiag_src[0] = inet->inet_rcv_saddr;
 110        r->id.idiag_dst[0] = inet->inet_daddr;
 111
 112        if (nla_put_u8(skb, INET_DIAG_SHUTDOWN, sk->sk_shutdown))
 113                goto errout;
 114
 115        /* IPv6 dual-stack sockets use inet->tos for IPv4 connections,
 116         * hence this needs to be included regardless of socket family.
 117         */
 118        if (ext & (1 << (INET_DIAG_TOS - 1)))
 119                if (nla_put_u8(skb, INET_DIAG_TOS, inet->tos) < 0)
 120                        goto errout;
 121
 122#if IS_ENABLED(CONFIG_IPV6)
 123        if (r->idiag_family == AF_INET6) {
 124                const struct ipv6_pinfo *np = inet6_sk(sk);
 125
 126                *(struct in6_addr *)r->id.idiag_src = np->rcv_saddr;
 127                *(struct in6_addr *)r->id.idiag_dst = np->daddr;
 128
 129                if (ext & (1 << (INET_DIAG_TCLASS - 1)))
 130                        if (nla_put_u8(skb, INET_DIAG_TCLASS, np->tclass) < 0)
 131                                goto errout;
 132        }
 133#endif
 134
 135        r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk));
 136        r->idiag_inode = sock_i_ino(sk);
 137
 138        if (ext & (1 << (INET_DIAG_MEMINFO - 1))) {
 139                struct inet_diag_meminfo minfo = {
 140                        .idiag_rmem = sk_rmem_alloc_get(sk),
 141                        .idiag_wmem = sk->sk_wmem_queued,
 142                        .idiag_fmem = sk->sk_forward_alloc,
 143                        .idiag_tmem = sk_wmem_alloc_get(sk),
 144                };
 145
 146                if (nla_put(skb, INET_DIAG_MEMINFO, sizeof(minfo), &minfo) < 0)
 147                        goto errout;
 148        }
 149
 150        if (ext & (1 << (INET_DIAG_SKMEMINFO - 1)))
 151                if (sock_diag_put_meminfo(sk, skb, INET_DIAG_SKMEMINFO))
 152                        goto errout;
 153
 154        if (icsk == NULL) {
 155                handler->idiag_get_info(sk, r, NULL);
 156                goto out;
 157        }
 158
 159#define EXPIRES_IN_MS(tmo)  DIV_ROUND_UP((tmo - jiffies) * 1000, HZ)
 160
 161        if (icsk->icsk_pending == ICSK_TIME_RETRANS) {
 162                r->idiag_timer = 1;
 163                r->idiag_retrans = icsk->icsk_retransmits;
 164                r->idiag_expires = EXPIRES_IN_MS(icsk->icsk_timeout);
 165        } else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
 166                r->idiag_timer = 4;
 167                r->idiag_retrans = icsk->icsk_probes_out;
 168                r->idiag_expires = EXPIRES_IN_MS(icsk->icsk_timeout);
 169        } else if (timer_pending(&sk->sk_timer)) {
 170                r->idiag_timer = 2;
 171                r->idiag_retrans = icsk->icsk_probes_out;
 172                r->idiag_expires = EXPIRES_IN_MS(sk->sk_timer.expires);
 173        } else {
 174                r->idiag_timer = 0;
 175                r->idiag_expires = 0;
 176        }
 177#undef EXPIRES_IN_MS
 178
 179        if (ext & (1 << (INET_DIAG_INFO - 1))) {
 180                attr = nla_reserve(skb, INET_DIAG_INFO,
 181                                   sizeof(struct tcp_info));
 182                if (!attr)
 183                        goto errout;
 184
 185                info = nla_data(attr);
 186        }
 187
 188        if ((ext & (1 << (INET_DIAG_CONG - 1))) && icsk->icsk_ca_ops)
 189                if (nla_put_string(skb, INET_DIAG_CONG,
 190                                   icsk->icsk_ca_ops->name) < 0)
 191                        goto errout;
 192
 193        handler->idiag_get_info(sk, r, info);
 194
 195        if (sk->sk_state < TCP_TIME_WAIT &&
 196            icsk->icsk_ca_ops && icsk->icsk_ca_ops->get_info)
 197                icsk->icsk_ca_ops->get_info(sk, ext, skb);
 198
 199out:
 200        return nlmsg_end(skb, nlh);
 201
 202errout:
 203        nlmsg_cancel(skb, nlh);
 204        return -EMSGSIZE;
 205}
 206EXPORT_SYMBOL_GPL(inet_sk_diag_fill);
 207
 208static int inet_csk_diag_fill(struct sock *sk,
 209                              struct sk_buff *skb, struct inet_diag_req_v2 *req,
 210                              struct user_namespace *user_ns,
 211                              u32 portid, u32 seq, u16 nlmsg_flags,
 212                              const struct nlmsghdr *unlh)
 213{
 214        return inet_sk_diag_fill(sk, inet_csk(sk),
 215                        skb, req, user_ns, portid, seq, nlmsg_flags, unlh);
 216}
 217
 218static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
 219                               struct sk_buff *skb, struct inet_diag_req_v2 *req,
 220                               u32 portid, u32 seq, u16 nlmsg_flags,
 221                               const struct nlmsghdr *unlh)
 222{
 223        long tmo;
 224        struct inet_diag_msg *r;
 225        struct nlmsghdr *nlh;
 226
 227        nlh = nlmsg_put(skb, portid, seq, unlh->nlmsg_type, sizeof(*r),
 228                        nlmsg_flags);
 229        if (!nlh)
 230                return -EMSGSIZE;
 231
 232        r = nlmsg_data(nlh);
 233        BUG_ON(tw->tw_state != TCP_TIME_WAIT);
 234
 235        tmo = tw->tw_ttd - jiffies;
 236        if (tmo < 0)
 237                tmo = 0;
 238
 239        r->idiag_family       = tw->tw_family;
 240        r->idiag_retrans      = 0;
 241        r->id.idiag_if        = tw->tw_bound_dev_if;
 242        sock_diag_save_cookie(tw, r->id.idiag_cookie);
 243        r->id.idiag_sport     = tw->tw_sport;
 244        r->id.idiag_dport     = tw->tw_dport;
 245        r->id.idiag_src[0]    = tw->tw_rcv_saddr;
 246        r->id.idiag_dst[0]    = tw->tw_daddr;
 247        r->idiag_state        = tw->tw_substate;
 248        r->idiag_timer        = 3;
 249        r->idiag_expires      = DIV_ROUND_UP(tmo * 1000, HZ);
 250        r->idiag_rqueue       = 0;
 251        r->idiag_wqueue       = 0;
 252        r->idiag_uid          = 0;
 253        r->idiag_inode        = 0;
 254#if IS_ENABLED(CONFIG_IPV6)
 255        if (tw->tw_family == AF_INET6) {
 256                const struct inet6_timewait_sock *tw6 =
 257                                                inet6_twsk((struct sock *)tw);
 258
 259                *(struct in6_addr *)r->id.idiag_src = tw6->tw_v6_rcv_saddr;
 260                *(struct in6_addr *)r->id.idiag_dst = tw6->tw_v6_daddr;
 261        }
 262#endif
 263
 264        return nlmsg_end(skb, nlh);
 265}
 266
 267static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
 268                        struct inet_diag_req_v2 *r,
 269                        struct user_namespace *user_ns,
 270                        u32 portid, u32 seq, u16 nlmsg_flags,
 271                        const struct nlmsghdr *unlh)
 272{
 273        if (sk->sk_state == TCP_TIME_WAIT)
 274                return inet_twsk_diag_fill((struct inet_timewait_sock *)sk,
 275                                           skb, r, portid, seq, nlmsg_flags,
 276                                           unlh);
 277        return inet_csk_diag_fill(sk, skb, r, user_ns, portid, seq, nlmsg_flags, unlh);
 278}
 279
 280int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb,
 281                const struct nlmsghdr *nlh, struct inet_diag_req_v2 *req)
 282{
 283        int err;
 284        struct sock *sk;
 285        struct sk_buff *rep;
 286        struct net *net = sock_net(in_skb->sk);
 287
 288        err = -EINVAL;
 289        if (req->sdiag_family == AF_INET) {
 290                sk = inet_lookup(net, hashinfo, req->id.idiag_dst[0],
 291                                 req->id.idiag_dport, req->id.idiag_src[0],
 292                                 req->id.idiag_sport, req->id.idiag_if);
 293        }
 294#if IS_ENABLED(CONFIG_IPV6)
 295        else if (req->sdiag_family == AF_INET6) {
 296                sk = inet6_lookup(net, hashinfo,
 297                                  (struct in6_addr *)req->id.idiag_dst,
 298                                  req->id.idiag_dport,
 299                                  (struct in6_addr *)req->id.idiag_src,
 300                                  req->id.idiag_sport,
 301                                  req->id.idiag_if);
 302        }
 303#endif
 304        else {
 305                goto out_nosk;
 306        }
 307
 308        err = -ENOENT;
 309        if (sk == NULL)
 310                goto out_nosk;
 311
 312        err = sock_diag_check_cookie(sk, req->id.idiag_cookie);
 313        if (err)
 314                goto out;
 315
 316        rep = nlmsg_new(sizeof(struct inet_diag_msg) +
 317                        sizeof(struct inet_diag_meminfo) +
 318                        sizeof(struct tcp_info) + 64, GFP_KERNEL);
 319        if (!rep) {
 320                err = -ENOMEM;
 321                goto out;
 322        }
 323
 324        err = sk_diag_fill(sk, rep, req,
 325                           sk_user_ns(NETLINK_CB(in_skb).ssk),
 326                           NETLINK_CB(in_skb).portid,
 327                           nlh->nlmsg_seq, 0, nlh);
 328        if (err < 0) {
 329                WARN_ON(err == -EMSGSIZE);
 330                nlmsg_free(rep);
 331                goto out;
 332        }
 333        err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid,
 334                              MSG_DONTWAIT);
 335        if (err > 0)
 336                err = 0;
 337
 338out:
 339        if (sk) {
 340                if (sk->sk_state == TCP_TIME_WAIT)
 341                        inet_twsk_put((struct inet_timewait_sock *)sk);
 342                else
 343                        sock_put(sk);
 344        }
 345out_nosk:
 346        return err;
 347}
 348EXPORT_SYMBOL_GPL(inet_diag_dump_one_icsk);
 349
 350static int inet_diag_get_exact(struct sk_buff *in_skb,
 351                               const struct nlmsghdr *nlh,
 352                               struct inet_diag_req_v2 *req)
 353{
 354        const struct inet_diag_handler *handler;
 355        int err;
 356
 357        handler = inet_diag_lock_handler(req->sdiag_protocol);
 358        if (IS_ERR(handler))
 359                err = PTR_ERR(handler);
 360        else
 361                err = handler->dump_one(in_skb, nlh, req);
 362        inet_diag_unlock_handler(handler);
 363
 364        return err;
 365}
 366
 367static int bitstring_match(const __be32 *a1, const __be32 *a2, int bits)
 368{
 369        int words = bits >> 5;
 370
 371        bits &= 0x1f;
 372
 373        if (words) {
 374                if (memcmp(a1, a2, words << 2))
 375                        return 0;
 376        }
 377        if (bits) {
 378                __be32 w1, w2;
 379                __be32 mask;
 380
 381                w1 = a1[words];
 382                w2 = a2[words];
 383
 384                mask = htonl((0xffffffff) << (32 - bits));
 385
 386                if ((w1 ^ w2) & mask)
 387                        return 0;
 388        }
 389
 390        return 1;
 391}
 392
 393
 394static int inet_diag_bc_run(const struct nlattr *_bc,
 395                const struct inet_diag_entry *entry)
 396{
 397        const void *bc = nla_data(_bc);
 398        int len = nla_len(_bc);
 399
 400        while (len > 0) {
 401                int yes = 1;
 402                const struct inet_diag_bc_op *op = bc;
 403
 404                switch (op->code) {
 405                case INET_DIAG_BC_NOP:
 406                        break;
 407                case INET_DIAG_BC_JMP:
 408                        yes = 0;
 409                        break;
 410                case INET_DIAG_BC_S_GE:
 411                        yes = entry->sport >= op[1].no;
 412                        break;
 413                case INET_DIAG_BC_S_LE:
 414                        yes = entry->sport <= op[1].no;
 415                        break;
 416                case INET_DIAG_BC_D_GE:
 417                        yes = entry->dport >= op[1].no;
 418                        break;
 419                case INET_DIAG_BC_D_LE:
 420                        yes = entry->dport <= op[1].no;
 421                        break;
 422                case INET_DIAG_BC_AUTO:
 423                        yes = !(entry->userlocks & SOCK_BINDPORT_LOCK);
 424                        break;
 425                case INET_DIAG_BC_S_COND:
 426                case INET_DIAG_BC_D_COND: {
 427                        struct inet_diag_hostcond *cond;
 428                        __be32 *addr;
 429
 430                        cond = (struct inet_diag_hostcond *)(op + 1);
 431                        if (cond->port != -1 &&
 432                            cond->port != (op->code == INET_DIAG_BC_S_COND ?
 433                                             entry->sport : entry->dport)) {
 434                                yes = 0;
 435                                break;
 436                        }
 437
 438                        if (op->code == INET_DIAG_BC_S_COND)
 439                                addr = entry->saddr;
 440                        else
 441                                addr = entry->daddr;
 442
 443                        if (cond->family != AF_UNSPEC &&
 444                            cond->family != entry->family) {
 445                                if (entry->family == AF_INET6 &&
 446                                    cond->family == AF_INET) {
 447                                        if (addr[0] == 0 && addr[1] == 0 &&
 448                                            addr[2] == htonl(0xffff) &&
 449                                            bitstring_match(addr + 3,
 450                                                            cond->addr,
 451                                                            cond->prefix_len))
 452                                                break;
 453                                }
 454                                yes = 0;
 455                                break;
 456                        }
 457
 458                        if (cond->prefix_len == 0)
 459                                break;
 460                        if (bitstring_match(addr, cond->addr,
 461                                            cond->prefix_len))
 462                                break;
 463                        yes = 0;
 464                        break;
 465                }
 466                }
 467
 468                if (yes) {
 469                        len -= op->yes;
 470                        bc += op->yes;
 471                } else {
 472                        len -= op->no;
 473                        bc += op->no;
 474                }
 475        }
 476        return len == 0;
 477}
 478
 479int inet_diag_bc_sk(const struct nlattr *bc, struct sock *sk)
 480{
 481        struct inet_diag_entry entry;
 482        struct inet_sock *inet = inet_sk(sk);
 483
 484        if (bc == NULL)
 485                return 1;
 486
 487        entry.family = sk->sk_family;
 488#if IS_ENABLED(CONFIG_IPV6)
 489        if (entry.family == AF_INET6) {
 490                struct ipv6_pinfo *np = inet6_sk(sk);
 491
 492                entry.saddr = np->rcv_saddr.s6_addr32;
 493                entry.daddr = np->daddr.s6_addr32;
 494        } else
 495#endif
 496        {
 497                entry.saddr = &inet->inet_rcv_saddr;
 498                entry.daddr = &inet->inet_daddr;
 499        }
 500        entry.sport = inet->inet_num;
 501        entry.dport = ntohs(inet->inet_dport);
 502        entry.userlocks = sk->sk_userlocks;
 503
 504        return inet_diag_bc_run(bc, &entry);
 505}
 506EXPORT_SYMBOL_GPL(inet_diag_bc_sk);
 507
 508static int valid_cc(const void *bc, int len, int cc)
 509{
 510        while (len >= 0) {
 511                const struct inet_diag_bc_op *op = bc;
 512
 513                if (cc > len)
 514                        return 0;
 515                if (cc == len)
 516                        return 1;
 517                if (op->yes < 4 || op->yes & 3)
 518                        return 0;
 519                len -= op->yes;
 520                bc  += op->yes;
 521        }
 522        return 0;
 523}
 524
 525/* Validate an inet_diag_hostcond. */
 526static bool valid_hostcond(const struct inet_diag_bc_op *op, int len,
 527                           int *min_len)
 528{
 529        int addr_len;
 530        struct inet_diag_hostcond *cond;
 531
 532        /* Check hostcond space. */
 533        *min_len += sizeof(struct inet_diag_hostcond);
 534        if (len < *min_len)
 535                return false;
 536        cond = (struct inet_diag_hostcond *)(op + 1);
 537
 538        /* Check address family and address length. */
 539        switch (cond->family) {
 540        case AF_UNSPEC:
 541                addr_len = 0;
 542                break;
 543        case AF_INET:
 544                addr_len = sizeof(struct in_addr);
 545                break;
 546        case AF_INET6:
 547                addr_len = sizeof(struct in6_addr);
 548                break;
 549        default:
 550                return false;
 551        }
 552        *min_len += addr_len;
 553        if (len < *min_len)
 554                return false;
 555
 556        /* Check prefix length (in bits) vs address length (in bytes). */
 557        if (cond->prefix_len > 8 * addr_len)
 558                return false;
 559
 560        return true;
 561}
 562
 563/* Validate a port comparison operator. */
 564static inline bool valid_port_comparison(const struct inet_diag_bc_op *op,
 565                                         int len, int *min_len)
 566{
 567        /* Port comparisons put the port in a follow-on inet_diag_bc_op. */
 568        *min_len += sizeof(struct inet_diag_bc_op);
 569        if (len < *min_len)
 570                return false;
 571        return true;
 572}
 573
 574static int inet_diag_bc_audit(const void *bytecode, int bytecode_len)
 575{
 576        const void *bc = bytecode;
 577        int  len = bytecode_len;
 578
 579        while (len > 0) {
 580                const struct inet_diag_bc_op *op = bc;
 581                int min_len = sizeof(struct inet_diag_bc_op);
 582
 583//printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len);
 584                switch (op->code) {
 585                case INET_DIAG_BC_S_COND:
 586                case INET_DIAG_BC_D_COND:
 587                        if (!valid_hostcond(bc, len, &min_len))
 588                                return -EINVAL;
 589                        break;
 590                case INET_DIAG_BC_S_GE:
 591                case INET_DIAG_BC_S_LE:
 592                case INET_DIAG_BC_D_GE:
 593                case INET_DIAG_BC_D_LE:
 594                        if (!valid_port_comparison(bc, len, &min_len))
 595                                return -EINVAL;
 596                        break;
 597                case INET_DIAG_BC_AUTO:
 598                case INET_DIAG_BC_JMP:
 599                case INET_DIAG_BC_NOP:
 600                        break;
 601                default:
 602                        return -EINVAL;
 603                }
 604
 605                if (op->code != INET_DIAG_BC_NOP) {
 606                        if (op->no < min_len || op->no > len + 4 || op->no & 3)
 607                                return -EINVAL;
 608                        if (op->no < len &&
 609                            !valid_cc(bytecode, bytecode_len, len - op->no))
 610                                return -EINVAL;
 611                }
 612
 613                if (op->yes < min_len || op->yes > len + 4 || op->yes & 3)
 614                        return -EINVAL;
 615                bc  += op->yes;
 616                len -= op->yes;
 617        }
 618        return len == 0 ? 0 : -EINVAL;
 619}
 620
 621static int inet_csk_diag_dump(struct sock *sk,
 622                              struct sk_buff *skb,
 623                              struct netlink_callback *cb,
 624                              struct inet_diag_req_v2 *r,
 625                              const struct nlattr *bc)
 626{
 627        if (!inet_diag_bc_sk(bc, sk))
 628                return 0;
 629
 630        return inet_csk_diag_fill(sk, skb, r,
 631                                  sk_user_ns(NETLINK_CB(cb->skb).ssk),
 632                                  NETLINK_CB(cb->skb).portid,
 633                                  cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
 634}
 635
 636static int inet_twsk_diag_dump(struct inet_timewait_sock *tw,
 637                               struct sk_buff *skb,
 638                               struct netlink_callback *cb,
 639                               struct inet_diag_req_v2 *r,
 640                               const struct nlattr *bc)
 641{
 642        if (bc != NULL) {
 643                struct inet_diag_entry entry;
 644
 645                entry.family = tw->tw_family;
 646#if IS_ENABLED(CONFIG_IPV6)
 647                if (tw->tw_family == AF_INET6) {
 648                        struct inet6_timewait_sock *tw6 =
 649                                                inet6_twsk((struct sock *)tw);
 650                        entry.saddr = tw6->tw_v6_rcv_saddr.s6_addr32;
 651                        entry.daddr = tw6->tw_v6_daddr.s6_addr32;
 652                } else
 653#endif
 654                {
 655                        entry.saddr = &tw->tw_rcv_saddr;
 656                        entry.daddr = &tw->tw_daddr;
 657                }
 658                entry.sport = tw->tw_num;
 659                entry.dport = ntohs(tw->tw_dport);
 660                entry.userlocks = 0;
 661
 662                if (!inet_diag_bc_run(bc, &entry))
 663                        return 0;
 664        }
 665
 666        return inet_twsk_diag_fill(tw, skb, r,
 667                                   NETLINK_CB(cb->skb).portid,
 668                                   cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
 669}
 670
 671/* Get the IPv4, IPv6, or IPv4-mapped-IPv6 local and remote addresses
 672 * from a request_sock. For IPv4-mapped-IPv6 we must map IPv4 to IPv6.
 673 */
 674static inline void inet_diag_req_addrs(const struct sock *sk,
 675                                       const struct request_sock *req,
 676                                       struct inet_diag_entry *entry)
 677{
 678        struct inet_request_sock *ireq = inet_rsk(req);
 679
 680#if IS_ENABLED(CONFIG_IPV6)
 681        if (sk->sk_family == AF_INET6) {
 682                if (req->rsk_ops->family == AF_INET6) {
 683                        entry->saddr = inet6_rsk(req)->loc_addr.s6_addr32;
 684                        entry->daddr = inet6_rsk(req)->rmt_addr.s6_addr32;
 685                } else if (req->rsk_ops->family == AF_INET) {
 686                        ipv6_addr_set_v4mapped(ireq->loc_addr,
 687                                               &entry->saddr_storage);
 688                        ipv6_addr_set_v4mapped(ireq->rmt_addr,
 689                                               &entry->daddr_storage);
 690                        entry->saddr = entry->saddr_storage.s6_addr32;
 691                        entry->daddr = entry->daddr_storage.s6_addr32;
 692                }
 693        } else
 694#endif
 695        {
 696                entry->saddr = &ireq->loc_addr;
 697                entry->daddr = &ireq->rmt_addr;
 698        }
 699}
 700
 701static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
 702                              struct request_sock *req,
 703                              struct user_namespace *user_ns,
 704                              u32 portid, u32 seq,
 705                              const struct nlmsghdr *unlh)
 706{
 707        const struct inet_request_sock *ireq = inet_rsk(req);
 708        struct inet_sock *inet = inet_sk(sk);
 709        struct inet_diag_msg *r;
 710        struct nlmsghdr *nlh;
 711        long tmo;
 712
 713        nlh = nlmsg_put(skb, portid, seq, unlh->nlmsg_type, sizeof(*r),
 714                        NLM_F_MULTI);
 715        if (!nlh)
 716                return -EMSGSIZE;
 717
 718        r = nlmsg_data(nlh);
 719        r->idiag_family = sk->sk_family;
 720        r->idiag_state = TCP_SYN_RECV;
 721        r->idiag_timer = 1;
 722        r->idiag_retrans = req->num_retrans;
 723
 724        r->id.idiag_if = sk->sk_bound_dev_if;
 725        sock_diag_save_cookie(req, r->id.idiag_cookie);
 726
 727        tmo = req->expires - jiffies;
 728        if (tmo < 0)
 729                tmo = 0;
 730
 731        r->id.idiag_sport = inet->inet_sport;
 732        r->id.idiag_dport = ireq->rmt_port;
 733        r->id.idiag_src[0] = ireq->loc_addr;
 734        r->id.idiag_dst[0] = ireq->rmt_addr;
 735        r->idiag_expires = jiffies_to_msecs(tmo);
 736        r->idiag_rqueue = 0;
 737        r->idiag_wqueue = 0;
 738        r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk));
 739        r->idiag_inode = 0;
 740#if IS_ENABLED(CONFIG_IPV6)
 741        if (r->idiag_family == AF_INET6) {
 742                struct inet_diag_entry entry;
 743                inet_diag_req_addrs(sk, req, &entry);
 744                memcpy(r->id.idiag_src, entry.saddr, sizeof(struct in6_addr));
 745                memcpy(r->id.idiag_dst, entry.daddr, sizeof(struct in6_addr));
 746        }
 747#endif
 748
 749        return nlmsg_end(skb, nlh);
 750}
 751
 752static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
 753                               struct netlink_callback *cb,
 754                               struct inet_diag_req_v2 *r,
 755                               const struct nlattr *bc)
 756{
 757        struct inet_diag_entry entry;
 758        struct inet_connection_sock *icsk = inet_csk(sk);
 759        struct listen_sock *lopt;
 760        struct inet_sock *inet = inet_sk(sk);
 761        int j, s_j;
 762        int reqnum, s_reqnum;
 763        int err = 0;
 764
 765        s_j = cb->args[3];
 766        s_reqnum = cb->args[4];
 767
 768        if (s_j > 0)
 769                s_j--;
 770
 771        entry.family = sk->sk_family;
 772
 773        read_lock_bh(&icsk->icsk_accept_queue.syn_wait_lock);
 774
 775        lopt = icsk->icsk_accept_queue.listen_opt;
 776        if (!lopt || !lopt->qlen)
 777                goto out;
 778
 779        if (bc != NULL) {
 780                entry.sport = inet->inet_num;
 781                entry.userlocks = sk->sk_userlocks;
 782        }
 783
 784        for (j = s_j; j < lopt->nr_table_entries; j++) {
 785                struct request_sock *req, *head = lopt->syn_table[j];
 786
 787                reqnum = 0;
 788                for (req = head; req; reqnum++, req = req->dl_next) {
 789                        struct inet_request_sock *ireq = inet_rsk(req);
 790
 791                        if (reqnum < s_reqnum)
 792                                continue;
 793                        if (r->id.idiag_dport != ireq->rmt_port &&
 794                            r->id.idiag_dport)
 795                                continue;
 796
 797                        if (bc) {
 798                                inet_diag_req_addrs(sk, req, &entry);
 799                                entry.dport = ntohs(ireq->rmt_port);
 800
 801                                if (!inet_diag_bc_run(bc, &entry))
 802                                        continue;
 803                        }
 804
 805                        err = inet_diag_fill_req(skb, sk, req,
 806                                               sk_user_ns(NETLINK_CB(cb->skb).ssk),
 807                                               NETLINK_CB(cb->skb).portid,
 808                                               cb->nlh->nlmsg_seq, cb->nlh);
 809                        if (err < 0) {
 810                                cb->args[3] = j + 1;
 811                                cb->args[4] = reqnum;
 812                                goto out;
 813                        }
 814                }
 815
 816                s_reqnum = 0;
 817        }
 818
 819out:
 820        read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock);
 821
 822        return err;
 823}
 824
 825void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb,
 826                struct netlink_callback *cb, struct inet_diag_req_v2 *r, struct nlattr *bc)
 827{
 828        int i, num;
 829        int s_i, s_num;
 830        struct net *net = sock_net(skb->sk);
 831
 832        s_i = cb->args[1];
 833        s_num = num = cb->args[2];
 834
 835        if (cb->args[0] == 0) {
 836                if (!(r->idiag_states & (TCPF_LISTEN | TCPF_SYN_RECV)))
 837                        goto skip_listen_ht;
 838
 839                for (i = s_i; i < INET_LHTABLE_SIZE; i++) {
 840                        struct sock *sk;
 841                        struct hlist_nulls_node *node;
 842                        struct inet_listen_hashbucket *ilb;
 843
 844                        num = 0;
 845                        ilb = &hashinfo->listening_hash[i];
 846                        spin_lock_bh(&ilb->lock);
 847                        sk_nulls_for_each(sk, node, &ilb->head) {
 848                                struct inet_sock *inet = inet_sk(sk);
 849
 850                                if (!net_eq(sock_net(sk), net))
 851                                        continue;
 852
 853                                if (num < s_num) {
 854                                        num++;
 855                                        continue;
 856                                }
 857
 858                                if (r->sdiag_family != AF_UNSPEC &&
 859                                                sk->sk_family != r->sdiag_family)
 860                                        goto next_listen;
 861
 862                                if (r->id.idiag_sport != inet->inet_sport &&
 863                                    r->id.idiag_sport)
 864                                        goto next_listen;
 865
 866                                if (!(r->idiag_states & TCPF_LISTEN) ||
 867                                    r->id.idiag_dport ||
 868                                    cb->args[3] > 0)
 869                                        goto syn_recv;
 870
 871                                if (inet_csk_diag_dump(sk, skb, cb, r, bc) < 0) {
 872                                        spin_unlock_bh(&ilb->lock);
 873                                        goto done;
 874                                }
 875
 876syn_recv:
 877                                if (!(r->idiag_states & TCPF_SYN_RECV))
 878                                        goto next_listen;
 879
 880                                if (inet_diag_dump_reqs(skb, sk, cb, r, bc) < 0) {
 881                                        spin_unlock_bh(&ilb->lock);
 882                                        goto done;
 883                                }
 884
 885next_listen:
 886                                cb->args[3] = 0;
 887                                cb->args[4] = 0;
 888                                ++num;
 889                        }
 890                        spin_unlock_bh(&ilb->lock);
 891
 892                        s_num = 0;
 893                        cb->args[3] = 0;
 894                        cb->args[4] = 0;
 895                }
 896skip_listen_ht:
 897                cb->args[0] = 1;
 898                s_i = num = s_num = 0;
 899        }
 900
 901        if (!(r->idiag_states & ~(TCPF_LISTEN | TCPF_SYN_RECV)))
 902                goto out;
 903
 904        for (i = s_i; i <= hashinfo->ehash_mask; i++) {
 905                struct inet_ehash_bucket *head = &hashinfo->ehash[i];
 906                spinlock_t *lock = inet_ehash_lockp(hashinfo, i);
 907                struct sock *sk;
 908                struct hlist_nulls_node *node;
 909
 910                num = 0;
 911
 912                if (hlist_nulls_empty(&head->chain) &&
 913                        hlist_nulls_empty(&head->twchain))
 914                        continue;
 915
 916                if (i > s_i)
 917                        s_num = 0;
 918
 919                spin_lock_bh(lock);
 920                sk_nulls_for_each(sk, node, &head->chain) {
 921                        struct inet_sock *inet = inet_sk(sk);
 922
 923                        if (!net_eq(sock_net(sk), net))
 924                                continue;
 925                        if (num < s_num)
 926                                goto next_normal;
 927                        if (!(r->idiag_states & (1 << sk->sk_state)))
 928                                goto next_normal;
 929                        if (r->sdiag_family != AF_UNSPEC &&
 930                                        sk->sk_family != r->sdiag_family)
 931                                goto next_normal;
 932                        if (r->id.idiag_sport != inet->inet_sport &&
 933                            r->id.idiag_sport)
 934                                goto next_normal;
 935                        if (r->id.idiag_dport != inet->inet_dport &&
 936                            r->id.idiag_dport)
 937                                goto next_normal;
 938                        if (inet_csk_diag_dump(sk, skb, cb, r, bc) < 0) {
 939                                spin_unlock_bh(lock);
 940                                goto done;
 941                        }
 942next_normal:
 943                        ++num;
 944                }
 945
 946                if (r->idiag_states & TCPF_TIME_WAIT) {
 947                        struct inet_timewait_sock *tw;
 948
 949                        inet_twsk_for_each(tw, node,
 950                                    &head->twchain) {
 951                                if (!net_eq(twsk_net(tw), net))
 952                                        continue;
 953
 954                                if (num < s_num)
 955                                        goto next_dying;
 956                                if (r->sdiag_family != AF_UNSPEC &&
 957                                                tw->tw_family != r->sdiag_family)
 958                                        goto next_dying;
 959                                if (r->id.idiag_sport != tw->tw_sport &&
 960                                    r->id.idiag_sport)
 961                                        goto next_dying;
 962                                if (r->id.idiag_dport != tw->tw_dport &&
 963                                    r->id.idiag_dport)
 964                                        goto next_dying;
 965                                if (inet_twsk_diag_dump(tw, skb, cb, r, bc) < 0) {
 966                                        spin_unlock_bh(lock);
 967                                        goto done;
 968                                }
 969next_dying:
 970                                ++num;
 971                        }
 972                }
 973                spin_unlock_bh(lock);
 974        }
 975
 976done:
 977        cb->args[1] = i;
 978        cb->args[2] = num;
 979out:
 980        ;
 981}
 982EXPORT_SYMBOL_GPL(inet_diag_dump_icsk);
 983
 984static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
 985                struct inet_diag_req_v2 *r, struct nlattr *bc)
 986{
 987        const struct inet_diag_handler *handler;
 988        int err = 0;
 989
 990        handler = inet_diag_lock_handler(r->sdiag_protocol);
 991        if (!IS_ERR(handler))
 992                handler->dump(skb, cb, r, bc);
 993        else
 994                err = PTR_ERR(handler);
 995        inet_diag_unlock_handler(handler);
 996
 997        return err ? : skb->len;
 998}
 999
1000static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
1001{
1002        struct nlattr *bc = NULL;
1003        int hdrlen = sizeof(struct inet_diag_req_v2);
1004
1005        if (nlmsg_attrlen(cb->nlh, hdrlen))
1006                bc = nlmsg_find_attr(cb->nlh, hdrlen, INET_DIAG_REQ_BYTECODE);
1007
1008        return __inet_diag_dump(skb, cb, nlmsg_data(cb->nlh), bc);
1009}
1010
1011static inline int inet_diag_type2proto(int type)
1012{
1013        switch (type) {
1014        case TCPDIAG_GETSOCK:
1015                return IPPROTO_TCP;
1016        case DCCPDIAG_GETSOCK:
1017                return IPPROTO_DCCP;
1018        default:
1019                return 0;
1020        }
1021}
1022
1023static int inet_diag_dump_compat(struct sk_buff *skb, struct netlink_callback *cb)
1024{
1025        struct inet_diag_req *rc = nlmsg_data(cb->nlh);
1026        struct inet_diag_req_v2 req;
1027        struct nlattr *bc = NULL;
1028        int hdrlen = sizeof(struct inet_diag_req);
1029
1030        req.sdiag_family = AF_UNSPEC; /* compatibility */
1031        req.sdiag_protocol = inet_diag_type2proto(cb->nlh->nlmsg_type);
1032        req.idiag_ext = rc->idiag_ext;
1033        req.idiag_states = rc->idiag_states;
1034        req.id = rc->id;
1035
1036        if (nlmsg_attrlen(cb->nlh, hdrlen))
1037                bc = nlmsg_find_attr(cb->nlh, hdrlen, INET_DIAG_REQ_BYTECODE);
1038
1039        return __inet_diag_dump(skb, cb, &req, bc);
1040}
1041
1042static int inet_diag_get_exact_compat(struct sk_buff *in_skb,
1043                               const struct nlmsghdr *nlh)
1044{
1045        struct inet_diag_req *rc = nlmsg_data(nlh);
1046        struct inet_diag_req_v2 req;
1047
1048        req.sdiag_family = rc->idiag_family;
1049        req.sdiag_protocol = inet_diag_type2proto(nlh->nlmsg_type);
1050        req.idiag_ext = rc->idiag_ext;
1051        req.idiag_states = rc->idiag_states;
1052        req.id = rc->id;
1053
1054        return inet_diag_get_exact(in_skb, nlh, &req);
1055}
1056
1057static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh)
1058{
1059        int hdrlen = sizeof(struct inet_diag_req);
1060        struct net *net = sock_net(skb->sk);
1061
1062        if (nlh->nlmsg_type >= INET_DIAG_GETSOCK_MAX ||
1063            nlmsg_len(nlh) < hdrlen)
1064                return -EINVAL;
1065
1066        if (nlh->nlmsg_flags & NLM_F_DUMP) {
1067                if (nlmsg_attrlen(nlh, hdrlen)) {
1068                        struct nlattr *attr;
1069
1070                        attr = nlmsg_find_attr(nlh, hdrlen,
1071                                               INET_DIAG_REQ_BYTECODE);
1072                        if (attr == NULL ||
1073                            nla_len(attr) < sizeof(struct inet_diag_bc_op) ||
1074                            inet_diag_bc_audit(nla_data(attr), nla_len(attr)))
1075                                return -EINVAL;
1076                }
1077                {
1078                        struct netlink_dump_control c = {
1079                                .dump = inet_diag_dump_compat,
1080                        };
1081                        return netlink_dump_start(net->diag_nlsk, skb, nlh, &c);
1082                }
1083        }
1084
1085        return inet_diag_get_exact_compat(skb, nlh);
1086}
1087
1088static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
1089{
1090        int hdrlen = sizeof(struct inet_diag_req_v2);
1091        struct net *net = sock_net(skb->sk);
1092
1093        if (nlmsg_len(h) < hdrlen)
1094                return -EINVAL;
1095
1096        if (h->nlmsg_flags & NLM_F_DUMP) {
1097                if (nlmsg_attrlen(h, hdrlen)) {
1098                        struct nlattr *attr;
1099                        attr = nlmsg_find_attr(h, hdrlen,
1100                                               INET_DIAG_REQ_BYTECODE);
1101                        if (attr == NULL ||
1102                            nla_len(attr) < sizeof(struct inet_diag_bc_op) ||
1103                            inet_diag_bc_audit(nla_data(attr), nla_len(attr)))
1104                                return -EINVAL;
1105                }
1106                {
1107                        struct netlink_dump_control c = {
1108                                .dump = inet_diag_dump,
1109                        };
1110                        return netlink_dump_start(net->diag_nlsk, skb, h, &c);
1111                }
1112        }
1113
1114        return inet_diag_get_exact(skb, h, nlmsg_data(h));
1115}
1116
1117static const struct sock_diag_handler inet_diag_handler = {
1118        .family = AF_INET,
1119        .dump = inet_diag_handler_dump,
1120};
1121
1122static const struct sock_diag_handler inet6_diag_handler = {
1123        .family = AF_INET6,
1124        .dump = inet_diag_handler_dump,
1125};
1126
1127int inet_diag_register(const struct inet_diag_handler *h)
1128{
1129        const __u16 type = h->idiag_type;
1130        int err = -EINVAL;
1131
1132        if (type >= IPPROTO_MAX)
1133                goto out;
1134
1135        mutex_lock(&inet_diag_table_mutex);
1136        err = -EEXIST;
1137        if (inet_diag_table[type] == NULL) {
1138                inet_diag_table[type] = h;
1139                err = 0;
1140        }
1141        mutex_unlock(&inet_diag_table_mutex);
1142out:
1143        return err;
1144}
1145EXPORT_SYMBOL_GPL(inet_diag_register);
1146
1147void inet_diag_unregister(const struct inet_diag_handler *h)
1148{
1149        const __u16 type = h->idiag_type;
1150
1151        if (type >= IPPROTO_MAX)
1152                return;
1153
1154        mutex_lock(&inet_diag_table_mutex);
1155        inet_diag_table[type] = NULL;
1156        mutex_unlock(&inet_diag_table_mutex);
1157}
1158EXPORT_SYMBOL_GPL(inet_diag_unregister);
1159
1160static int __init inet_diag_init(void)
1161{
1162        const int inet_diag_table_size = (IPPROTO_MAX *
1163                                          sizeof(struct inet_diag_handler *));
1164        int err = -ENOMEM;
1165
1166        inet_diag_table = kzalloc(inet_diag_table_size, GFP_KERNEL);
1167        if (!inet_diag_table)
1168                goto out;
1169
1170        err = sock_diag_register(&inet_diag_handler);
1171        if (err)
1172                goto out_free_nl;
1173
1174        err = sock_diag_register(&inet6_diag_handler);
1175        if (err)
1176                goto out_free_inet;
1177
1178        sock_diag_register_inet_compat(inet_diag_rcv_msg_compat);
1179out:
1180        return err;
1181
1182out_free_inet:
1183        sock_diag_unregister(&inet_diag_handler);
1184out_free_nl:
1185        kfree(inet_diag_table);
1186        goto out;
1187}
1188
1189static void __exit inet_diag_exit(void)
1190{
1191        sock_diag_unregister(&inet6_diag_handler);
1192        sock_diag_unregister(&inet_diag_handler);
1193        sock_diag_unregister_inet_compat(inet_diag_rcv_msg_compat);
1194        kfree(inet_diag_table);
1195}
1196
1197module_init(inet_diag_init);
1198module_exit(inet_diag_exit);
1199MODULE_LICENSE("GPL");
1200MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 2 /* AF_INET */);
1201MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 10 /* AF_INET6 */);
1202