Print this page
4596 Callers of ip_srcid_find_id() need to be more careful

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/inet/ip/ip_srcid.c
          +++ new/usr/src/uts/common/inet/ip/ip_srcid.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
       24 + *
       25 + * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
  24   26   */
  25   27  
  26   28  /*
  27   29   * This is used to support the hidden __sin6_src_id in the sockaddr_in6
  28   30   * structure which is there to ensure that applications (such as UDP apps)
  29   31   * which get an address from recvfrom and use that address in a sendto
  30   32   * or connect will by default use the same source address in the "response"
  31   33   * as the destination address in the "request" they received.
  32   34   *
  33   35   * This is built using some new functions (in IP - doing their own locking
↓ open down ↓ 182 lines elided ↑ open up ↑
 216  218                  ASSERT(smp->sm_refcnt != 0);
 217  219                  id = smp->sm_srcid;
 218  220          }
 219  221          rw_exit(&ipst->ips_srcid_lock);
 220  222          return (id);
 221  223  }
 222  224  
 223  225  /*
 224  226   * Map from a source id to an address.
 225  227   * If the id is unknown return the unspecified address.
      228 + *
      229 + * For known IDs, check if the returned address is v4mapped or not, and
      230 + * return B_TRUE if it matches the desired v4mapped state or not.  This
      231 + * prevents a broken app from requesting (via __sin6_src_id) a v4mapped
      232 + * address for a v6 destination, or vice versa.
      233 + *
      234 + * "addr" will not be set if we return B_FALSE.
 226  235   */
 227      -void
      236 +boolean_t
 228  237  ip_srcid_find_id(uint_t id, in6_addr_t *addr, zoneid_t zoneid,
 229      -    netstack_t *ns)
      238 +    boolean_t v4mapped, netstack_t *ns)
 230  239  {
 231  240          srcid_map_t     **smpp;
 232  241          srcid_map_t     *smp;
 233  242          ip_stack_t      *ipst = ns->netstack_ip;
      243 +        boolean_t       rc;
 234  244  
 235  245          rw_enter(&ipst->ips_srcid_lock, RW_READER);
 236  246          smpp = srcid_lookup_id(id, ipst);
 237  247          smp = *smpp;
 238  248          if (smp == NULL || (smp->sm_zoneid != zoneid && zoneid != ALL_ZONES)) {
 239  249                  /* Not preset */
 240  250                  ip1dbg(("ip_srcid_find_id: unknown %u or in wrong zone\n", id));
 241  251                  *addr = ipv6_all_zeros;
      252 +                rc = B_TRUE;
 242  253          } else {
 243  254                  ASSERT(smp->sm_refcnt != 0);
 244      -                *addr = smp->sm_addr;
      255 +                /*
      256 +                 * The caller tells us if it expects a v4mapped address.
      257 +                 * Use it, along with the property of "addr" to set the rc.
      258 +                 */
      259 +                if (IN6_IS_ADDR_V4MAPPED(&smp->sm_addr))
      260 +                        rc = v4mapped;  /* We want a v4mapped address. */
      261 +                else
      262 +                        rc = !v4mapped; /* We don't want a v4mapped address. */
      263 +
      264 +                if (rc)
      265 +                        *addr = smp->sm_addr;
      266 +
 245  267          }
 246  268          rw_exit(&ipst->ips_srcid_lock);
      269 +        return (rc);
 247  270  }
 248  271  
 249  272  /* Assign the next available ID */
 250  273  static uint_t
 251  274  srcid_nextid(ip_stack_t *ipst)
 252  275  {
 253  276          uint_t id;
 254  277          srcid_map_t     **smpp;
 255  278  
 256  279          ASSERT(rw_owner(&ipst->ips_srcid_lock) == curthread);
↓ open down ↓ 59 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX