Print this page
    
8927 sadb_x_kmc_t's KM cookie should be 64-bits (fix improper upstream)
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/test/os-tests/tests/pf_key/kmc-updater.c
          +++ new/usr/src/test/os-tests/tests/pf_key/kmc-updater.c
   1    1  /*
   2    2   * This file and its contents are supplied under the terms of the
   3    3   * Common Development and Distribution License ("CDDL"), version 1.0.
   4    4   * You may only use this file in accordance with the terms of version
   5    5   * 1.0 of the CDDL.
   6    6   *
   7    7   * A full copy of the text of the CDDL should have accompanied this
   8    8   * source.  A copy of the CDDL is also available via the Internet at
   9    9   * http://www.illumos.org/license/CDDL.
  10   10   */
  11   11  
  12   12  /*
  13   13   * Copyright 2017 Joyent, Inc.
  14   14   */
  15   15  
  16   16  #include <sys/socket.h>
  17   17  #include <net/pfkeyv2.h>
  18   18  #include <stdio.h>
  
    | 
      ↓ open down ↓ | 
    18 lines elided | 
    
      ↑ open up ↑ | 
  
  19   19  #include <errno.h>
  20   20  #include <err.h>
  21   21  #include <unistd.h>
  22   22  #include <stdlib.h>
  23   23  #include <string.h>
  24   24  
  25   25  #define COOKIE64 0xc0ffee4afee01deaULL
  26   26  #define COOKIE32 0x90125
  27   27  #define RESERVED 0xc0ffee
  28   28  
       29 +#define EXIT_SETUP_FAIL -1
       30 +#define EXIT_TEST_FAIL 1
       31 +#define EXIT_SUCCESS 0
       32 +
  29   33  /*
  30   34   * Exits app on failure.
  31   35   */
  32   36  static void
  33   37  write_and_read(int s, sadb_msg_t *samsg, uint64_t *readbuf, int readlen,
  34   38      char *msgtypestr)
  35   39  {
  36      -        int rc;
       40 +        ssize_t rc;
  37   41          uint8_t msgtype = samsg->sadb_msg_type;
  38   42          pid_t pid = samsg->sadb_msg_pid;
  39   43          uint8_t seq = samsg->sadb_msg_seq;
  40   44  
  41   45          rc = write(s, samsg, SADB_64TO8(samsg->sadb_msg_len));
  42   46          if (rc == -1)
  43      -                err(-1, "%s write error", msgtypestr);
       47 +                err(EXIT_SETUP_FAIL, "%s write error", msgtypestr);
  44   48  
  45   49          /* Yes, parameter re-use, but we're done writing. */
  46   50          samsg = (sadb_msg_t *)readbuf;
  47   51          do {
  48   52                  rc = read(s, readbuf, readlen);
  49   53                  if (rc == -1)
  50      -                        err(-1, "%s read reply error", msgtypestr);
       54 +                        err(EXIT_SETUP_FAIL, "%s read reply error", msgtypestr);
  51   55          } while (samsg->sadb_msg_seq != seq || samsg->sadb_msg_pid != pid ||
  52   56              samsg->sadb_msg_type != msgtype);
  53   57  
  54   58          if (samsg->sadb_msg_errno != 0) {
  55   59                  errno = samsg->sadb_msg_errno;
  56      -                err(-1, "%s reply has error (diag = %d)", msgtypestr,
  57      -                    samsg->sadb_x_msg_diagnostic);
       60 +                err(EXIT_SETUP_FAIL, "%s reply has error (diag = %d)",
       61 +                    msgtypestr, samsg->sadb_x_msg_diagnostic);
  58   62          }
  59   63  }
  60   64  
  61   65  int
  62   66  main(int argc, char *argv[])
  63   67  {
  64   68          uint32_t spi;
  65   69          sadb_ext_t *ext;
  66   70          sadb_sa_t *saext;
  67   71          sadb_msg_t *samsg;
  68   72          sadb_address_t *dstext, *srcext;
  69   73          sadb_x_kmc_t *kmcext;
  70   74          struct sockaddr_in *sin;
  
    | 
      ↓ open down ↓ | 
    3 lines elided | 
    
      ↑ open up ↑ | 
  
  71   75          uint64_t writebuf[20];          /* PF_KEY likes 64-bit alignment. */
  72   76          uint64_t readbuf[128];
  73   77          uint64_t *extptr, *endptr;
  74   78          pid_t pid = getpid();
  75   79          boolean_t do_64_test;
  76   80          int s;
  77   81  
  78   82          if (argc != 2 && argc != 3) {
  79   83                  (void) fprintf(stderr, "Usage: %s <spi-value> {64}\n",
  80   84                      argv[0]);
  81      -                exit(-1);
       85 +                exit(EXIT_SETUP_FAIL);
  82   86          }
  83   87          do_64_test = (argc == 3);
  84   88  
       89 +        errno = 0;      /* Clear for strtoul() call. */
  85   90          spi = strtoul(argv[1], NULL, 0);
  86   91          if (spi == 0) {
  87   92                  if (errno != 0) {
  88      -                        err(-1, "Argument %s is not a parsable number:",
  89      -                            argv[1]);
       93 +                        err(EXIT_SETUP_FAIL,
       94 +                            "Argument %s is not a parsable number:", argv[1]);
  90   95                  } else {
  91   96                          errno = EINVAL;
  92      -                        err(-1, "Zero SPI not allowed:");
       97 +                        err(EXIT_SETUP_FAIL, "Zero SPI not allowed:");
  93   98                  }
  94   99          }
  95  100  
  96  101          s = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
  97  102          if (s == -1)
  98      -                err(-1, "socket(PF_KEY)");
      103 +                err(EXIT_SETUP_FAIL, "socket(PF_KEY)");
  99  104  
 100  105          /* Base message. */
 101  106          samsg = (sadb_msg_t *)writebuf;
 102  107          samsg->sadb_msg_version = PF_KEY_V2;
 103  108          samsg->sadb_msg_type = SADB_UPDATE;
 104  109          samsg->sadb_msg_errno = 0;
 105  110          samsg->sadb_msg_satype = SADB_SATYPE_AH;
 106  111          samsg->sadb_msg_reserved = 0;
 107  112          samsg->sadb_msg_seq = 1;
 108  113          samsg->sadb_msg_pid = pid;
 109  114          samsg->sadb_msg_len = SADB_8TO64(sizeof (*samsg) + sizeof (*saext) +
 110  115              2 * (sizeof (*dstext) + sizeof (*sin)) + sizeof (*kmcext));
 111  116  
 112  117          /* SA extension. Only used to set the SPI. */
 113  118          saext = (sadb_sa_t *)(samsg + 1);
 114  119          memset(saext, 0, sizeof (*saext));
 115  120          saext->sadb_sa_len = SADB_8TO64(sizeof (*saext));
 116  121          saext->sadb_sa_exttype = SADB_EXT_SA;
 117  122          saext->sadb_sa_spi = htonl(spi);
 118  123          saext->sadb_sa_state = SADB_SASTATE_MATURE;
 119  124  
 120  125          /* Destination IP, always 127.0.0.1 for this test. */
 121  126          dstext = (sadb_address_t *)(saext + 1);
 122  127          dstext->sadb_address_len = SADB_8TO64(sizeof (*dstext) + sizeof (*sin));
 123  128          dstext->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
 124  129          dstext->sadb_address_proto = 0;
 125  130          dstext->sadb_address_prefixlen = 0;
 126  131          dstext->sadb_address_reserved = 0;
 127  132          sin = (struct sockaddr_in *)(dstext + 1);
 128  133          sin->sin_family = AF_INET;
 129  134          sin->sin_port = 0;
 130  135          sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
 131  136  
 132  137          /* PF_KEY requires a source address, even if it's a wildcard. */
 133  138          srcext = (sadb_address_t *)(sin + 1);
 134  139          srcext->sadb_address_len = SADB_8TO64(sizeof (*srcext) + sizeof (*sin));
 135  140          srcext->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
 136  141          srcext->sadb_address_proto = 0;
 137  142          srcext->sadb_address_prefixlen = 0;
 138  143          srcext->sadb_address_reserved = 0;
 139  144          sin = (struct sockaddr_in *)(srcext + 1);
 140  145          sin->sin_family = AF_INET;
 141  146          sin->sin_port = 0;
 142  147          sin->sin_addr.s_addr = 0;
 143  148  
 144  149          /*
 145  150           * KM cookie. Depending, either make it IKEv1, 32-bit, AND store
 146  151           * garbage in the reserved field, or just put a big 64-bit cookie in.
 147  152           */
 148  153          kmcext = (sadb_x_kmc_t *)(sin + 1);
 149  154          kmcext->sadb_x_kmc_len = SADB_8TO64(sizeof (*kmcext));
 150  155          kmcext->sadb_x_kmc_exttype = SADB_X_EXT_KM_COOKIE;
 151  156          if (do_64_test) {
 152  157                  /* 64-bit cookie test.  KINK is non-zero, and non-IKEv1. */
 153  158                  kmcext->sadb_x_kmc_proto = SADB_X_KMP_KINK;
 154  159                  kmcext->sadb_x_kmc_cookie64 = COOKIE64;
 155  160          } else {
 156  161                  /* IKEv1 32-bit cookie test. */
 157  162                  kmcext->sadb_x_kmc_proto = SADB_X_KMP_IKE;
 158  163                  kmcext->sadb_x_kmc_cookie = COOKIE32;
 159  164                  kmcext->sadb_x_kmc_reserved = RESERVED;
 160  165          }
 161  166  
 162  167          write_and_read(s, samsg, readbuf, sizeof (readbuf), "SADB_UPDATE");
 163  168  
 164  169          /*
 165  170           * Okay, it worked!  Now let's find the KMC reported back from the
 166  171           * kernel.
 167  172           */
 168  173          samsg->sadb_msg_type = SADB_GET;
 169  174          samsg->sadb_msg_len -= SADB_8TO64(sizeof (*kmcext));
 170  175  
 171  176          /* Everything else in writebuf is good to go. */
 172  177          write_and_read(s, samsg, readbuf, sizeof (readbuf), "SADB_GET");
 173  178  
 174  179          /* Actually find the KMC extension. (expand for loop for readability) */
 175  180          samsg = (sadb_msg_t *)readbuf;
 176  181          extptr = (uint64_t *)(samsg + 1);
 177  182          endptr = extptr + samsg->sadb_msg_len - SADB_8TO64(sizeof (*samsg));
  
    | 
      ↓ open down ↓ | 
    69 lines elided | 
    
      ↑ open up ↑ | 
  
 178  183          ext = (sadb_ext_t *)extptr;
 179  184  
 180  185          while ((extptr < endptr) &&
 181  186              (ext->sadb_ext_type != SADB_X_EXT_KM_COOKIE)) {
 182  187                  extptr += ext->sadb_ext_len;
 183  188                  ext = (sadb_ext_t *)extptr;
 184  189          }
 185  190  
 186  191          if (extptr == endptr) {
 187  192                  (void) fprintf(stderr, "Can't find KMC extension in reply.\n");
 188      -                exit(-1);
      193 +                exit(EXIT_SETUP_FAIL);
 189  194          }
 190  195          kmcext = (sadb_x_kmc_t *)extptr;
 191  196  
 192  197          if (do_64_test) {
 193  198                  if (kmcext->sadb_x_kmc_proto != SADB_X_KMP_KINK ||
 194  199                      kmcext->sadb_x_kmc_cookie64 != COOKIE64) {
 195  200                          (void) fprintf(stderr, "Unexpected 64-bit results: "
 196  201                              "KMC received was %d, expecting %d,\n",
 197  202                              kmcext->sadb_x_kmc_proto, SADB_X_KMP_KINK);
 198  203                          (void) fprintf(stderr, "64-bit cookie recevied was "
 199  204                              "0x%"PRIx64", expecting 0x%"PRIx64"\n",
 200  205                              kmcext->sadb_x_kmc_cookie64, COOKIE64);
 201      -                        exit(1);
      206 +                        exit(EXIT_TEST_FAIL);
 202  207                  }
 203  208          } else {
 204  209                  if (kmcext->sadb_x_kmc_proto != SADB_X_KMP_IKE ||
 205  210                      kmcext->sadb_x_kmc_cookie != COOKIE32 ||
 206  211                      kmcext->sadb_x_kmc_reserved != 0) {
 207  212                          (void) fprintf(stderr, "Unexpected IKE/32-bit results:"
 208  213                              " KMC received was %d, expecting %d,\n",
 209  214                              kmcext->sadb_x_kmc_proto, SADB_X_KMP_IKE);
 210  215                          (void) fprintf(stderr, "32-bit cookie recevied was "
 211  216                              "0x%"PRIx32", expecting 0x%"PRIx32"\n",
 212  217                              kmcext->sadb_x_kmc_cookie64, COOKIE32);
 213  218                          (void) fprintf(stderr, "32-bit reserved recevied was "
 214  219                              "0x%"PRIx32", expecting 0\n",
 215  220                              kmcext->sadb_x_kmc_cookie64);
 216      -                        exit(1);
      221 +                        exit(EXIT_TEST_FAIL);
 217  222                  }
 218  223          }
 219  224  
 220      -        exit(0);
      225 +        exit(EXIT_SUCCESS);
 221  226  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX