Print this page
Code review comments from pmooney (sundry), and igork (screwups in zonecfg refactoring)
7029 want per-process exploit mitigation features (secflags)
7030 want basic address space layout randomization (aslr)
7031 noexec_user_stack should be a secflag
7032 want a means to forbid mappings around NULL.

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/zonecfg/zonecfg.c
          +++ new/usr/src/cmd/zonecfg/zonecfg.c
↓ open down ↓ 45 lines elided ↑ open up ↑
  46   46   * The rest of this module consists of the various function handlers and
  47   47   * their helper functions.  Some of these functions, particularly the
  48   48   * X_to_str() functions, which maps command, resource and property numbers
  49   49   * to strings, are used quite liberally, as doing so results in a better
  50   50   * program w/rt I18N, reducing the need for translation notes.
  51   51   */
  52   52  
  53   53  #include <sys/mntent.h>
  54   54  #include <sys/varargs.h>
  55   55  #include <sys/sysmacros.h>
       56 +#include <sys/secflags.h>
  56   57  
  57   58  #include <errno.h>
  58   59  #include <fcntl.h>
  59   60  #include <strings.h>
  60   61  #include <unistd.h>
  61   62  #include <ctype.h>
  62   63  #include <stdlib.h>
  63   64  #include <assert.h>
  64   65  #include <sys/stat.h>
  65   66  #include <zone.h>
↓ open down ↓ 114 lines elided ↑ open up ↑
 180  181          ALIAS_MAXMSGIDS,
 181  182          ALIAS_MAXSEMIDS,
 182  183          ALIAS_SHARES,
 183  184          "scheduling-class",
 184  185          "ip-type",
 185  186          "capped-cpu",
 186  187          "hostid",
 187  188          "admin",
 188  189          "fs-allowed",
 189  190          ALIAS_MAXPROCS,
      191 +        "security-flags",
 190  192          NULL
 191  193  };
 192  194  
 193  195  /* These *must* match the order of the PT_ define's from zonecfg.h */
 194  196  char *prop_types[] = {
 195  197          "unknown",
 196  198          "zonename",
 197  199          "zonepath",
 198  200          "autoboot",
 199  201          "pool",
↓ open down ↓ 27 lines elided ↑ open up ↑
 227  229          ALIAS_MAXSWAP,
 228  230          "scheduling-class",
 229  231          "ip-type",
 230  232          "defrouter",
 231  233          "hostid",
 232  234          "user",
 233  235          "auths",
 234  236          "fs-allowed",
 235  237          ALIAS_MAXPROCS,
 236  238          "allowed-address",
      239 +        "default",
      240 +        "lower",
      241 +        "upper",
 237  242          NULL
 238  243  };
 239  244  
 240  245  /* These *must* match the order of the PROP_VAL_ define's from zonecfg.h */
 241  246  static char *prop_val_types[] = {
 242  247          "simple",
 243  248          "complex",
 244  249          "list",
 245  250  };
 246  251  
↓ open down ↓ 28 lines elided ↑ open up ↑
 275  280          "add fs",
 276  281          "add net",
 277  282          "add device",
 278  283          "add rctl",
 279  284          "add attr",
 280  285          "add dataset",
 281  286          "add dedicated-cpu",
 282  287          "add capped-cpu",
 283  288          "add capped-memory",
 284  289          "add admin",
      290 +        "add security-flags",
 285  291          NULL
 286  292  };
 287  293  
 288  294  static const char *clear_cmds[] = {
 289  295          "clear autoboot",
 290  296          "clear pool",
 291  297          "clear limitpriv",
 292  298          "clear bootargs",
 293  299          "clear scheduling-class",
 294  300          "clear ip-type",
↓ open down ↓ 11 lines elided ↑ open up ↑
 306  312          "remove fs ",
 307  313          "remove net ",
 308  314          "remove device ",
 309  315          "remove rctl ",
 310  316          "remove attr ",
 311  317          "remove dataset ",
 312  318          "remove dedicated-cpu ",
 313  319          "remove capped-cpu ",
 314  320          "remove capped-memory ",
 315  321          "remove admin ",
      322 +        "remove security-flags",
 316  323          NULL
 317  324  };
 318  325  
 319  326  static const char *select_cmds[] = {
 320  327          "select fs ",
 321  328          "select net ",
 322  329          "select device ",
 323  330          "select rctl ",
 324  331          "select attr ",
 325  332          "select dataset ",
 326  333          "select dedicated-cpu",
 327  334          "select capped-cpu",
 328  335          "select capped-memory",
 329  336          "select admin",
      337 +        "select security-flags",
 330  338          NULL
 331  339  };
 332  340  
 333  341  static const char *set_cmds[] = {
 334  342          "set zonename=",
 335  343          "set zonepath=",
 336  344          "set brand=",
 337  345          "set autoboot=",
 338  346          "set pool=",
 339  347          "set limitpriv=",
↓ open down ↓ 15 lines elided ↑ open up ↑
 355  363  static const char *info_cmds[] = {
 356  364          "info fs ",
 357  365          "info net ",
 358  366          "info device ",
 359  367          "info rctl ",
 360  368          "info attr ",
 361  369          "info dataset ",
 362  370          "info capped-memory",
 363  371          "info dedicated-cpu",
 364  372          "info capped-cpu",
      373 +        "info security-flags",
 365  374          "info zonename",
 366  375          "info zonepath",
 367  376          "info autoboot",
 368  377          "info pool",
 369  378          "info limitpriv",
 370  379          "info bootargs",
 371  380          "info brand",
 372  381          "info scheduling-class",
 373  382          "info ip-type",
 374  383          "info max-lwps",
↓ open down ↓ 122 lines elided ↑ open up ↑
 497  506          "cancel",
 498  507          "end",
 499  508          "exit",
 500  509          "help",
 501  510          "info",
 502  511          "set user=",
 503  512          "set auths=",
 504  513          NULL
 505  514  };
 506  515  
      516 +static const char *secflags_res_scope_cmds[] = {
      517 +        "cancel",
      518 +        "end",
      519 +        "exit",
      520 +        "set default=",
      521 +        "set lower=",
      522 +        "set upper=",
      523 +        NULL
      524 +};
      525 +
 507  526  struct xif {
 508  527          struct xif      *xif_next;
 509  528          char            xif_name[LIFNAMSIZ];
 510  529          boolean_t       xif_has_address;
 511  530          boolean_t       xif_has_defrouter;
 512  531  };
 513  532  
 514  533  /* Global variables */
 515  534  
 516  535  /* list of network interfaces specified for exclusive IP zone */
↓ open down ↓ 57 lines elided ↑ open up ↑
 574  593   */
 575  594  static struct zone_fstab        old_fstab, in_progress_fstab;
 576  595  static struct zone_nwiftab      old_nwiftab, in_progress_nwiftab;
 577  596  static struct zone_devtab       old_devtab, in_progress_devtab;
 578  597  static struct zone_rctltab      old_rctltab, in_progress_rctltab;
 579  598  static struct zone_attrtab      old_attrtab, in_progress_attrtab;
 580  599  static struct zone_dstab        old_dstab, in_progress_dstab;
 581  600  static struct zone_psettab      old_psettab, in_progress_psettab;
 582  601  static struct zone_mcaptab      old_mcaptab, in_progress_mcaptab;
 583  602  static struct zone_admintab     old_admintab, in_progress_admintab;
      603 +static struct zone_secflagstab  old_secflagstab, in_progress_secflagstab;
 584  604  
 585  605  static GetLine *gl;     /* The gl_get_line() resource object */
 586  606  
 587  607  static void bytes_to_units(char *str, char *buf, int bufsize);
 588  608  
 589  609  /* Functions begin here */
 590  610  
 591  611  static boolean_t
 592  612  initial_match(const char *line1, const char *line2, int word_end)
 593  613  {
↓ open down ↓ 57 lines elided ↑ open up ↑
 651  671          case RT_DATASET:
 652  672                  return (add_stuff(cpl, line, dataset_res_scope_cmds, word_end));
 653  673          case RT_DCPU:
 654  674                  return (add_stuff(cpl, line, pset_res_scope_cmds, word_end));
 655  675          case RT_PCAP:
 656  676                  return (add_stuff(cpl, line, pcap_res_scope_cmds, word_end));
 657  677          case RT_MCAP:
 658  678                  return (add_stuff(cpl, line, mcap_res_scope_cmds, word_end));
 659  679          case RT_ADMIN:
 660  680                  return (add_stuff(cpl, line, admin_res_scope_cmds, word_end));
      681 +        case RT_SECFLAGS:
      682 +                return (add_stuff(cpl, line, secflags_res_scope_cmds,
      683 +                    word_end));
      684 +
 661  685          }
 662  686          return (0);
 663  687  }
 664  688  
 665  689  /*
 666  690   * For the main CMD_func() functions below, several of them call getopt()
 667  691   * then check optind against argc to make sure an extra parameter was not
 668  692   * passed in.  The reason this is not caught in the grammar is that the
 669  693   * grammar just checks for a miscellaneous TOKEN, which is *expected* to
 670  694   * be "-F" (for example), but could be anything.  So (for example) this
↓ open down ↓ 295 lines elided ↑ open up ↑
 966  990                  if (stat(fname, &stat_buf) != -1) {
 967  991                          /* successful find of the file */
 968  992                          return (0);
 969  993                  }
 970  994          } while (cp != NULL);
 971  995  
 972  996          return (-1);
 973  997  }
 974  998  
 975  999  static FILE *
 976      -pager_open(void) {
     1000 +pager_open(void)
     1001 +{
 977 1002          FILE *newfp;
 978 1003          char *pager, *space;
 979 1004  
 980 1005          pager = getenv("PAGER");
 981 1006          if (pager == NULL || *pager == '\0')
 982 1007                  pager = PAGER;
 983 1008  
 984 1009          space = strchr(pager, ' ');
 985 1010          if (space)
 986 1011                  *space = '\0';
↓ open down ↓ 5 lines elided ↑ open up ↑
 992 1017                              strerror(errno));
 993 1018                  return (newfp);
 994 1019          } else {
 995 1020                  zerr(gettext("PAGER %s does not exist (%s)."),
 996 1021                      pager, strerror(errno));
 997 1022          }
 998 1023          return (NULL);
 999 1024  }
1000 1025  
1001 1026  static void
1002      -pager_close(FILE *fp) {
     1027 +pager_close(FILE *fp)
     1028 +{
1003 1029          int status;
1004 1030  
1005 1031          status = pclose(fp);
1006 1032          if (status == -1)
1007 1033                  zerr(gettext("PAGER close failed (%s)."),
1008 1034                      strerror(errno));
1009 1035  }
1010 1036  
1011 1037  /*
1012 1038   * Called with verbose TRUE when help is explicitly requested, FALSE for
↓ open down ↓ 207 lines elided ↑ open up ↑
1220 1246                              "only applicable to this zone.\n"),
1221 1247                              rt_to_str(resource_scope));
1222 1248                          (void) fprintf(fp, gettext("Valid commands:\n"));
1223 1249                          (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1224 1250                              pt_to_str(PT_USER),
1225 1251                              gettext("<single user or role name>"));
1226 1252                          (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1227 1253                              pt_to_str(PT_AUTHS),
1228 1254                              gettext("<comma separated list>"));
1229 1255                          break;
     1256 +                case RT_SECFLAGS:
     1257 +                        (void) fprintf(fp, gettext("The '%s' resource scope is "
     1258 +                            "used to specify the default security-flags\n"
     1259 +                            "of this zone, and their upper and lower bound.\n"),
     1260 +                            rt_to_str(resource_scope));
     1261 +                        (void) fprintf(fp, "\t%s %s=%s\n",
     1262 +                            cmd_to_str(CMD_SET), pt_to_str(PT_DEFAULT),
     1263 +                            gettext("<security flags>"));
     1264 +                        (void) fprintf(fp, "\t%s %s=%s\n",
     1265 +                            cmd_to_str(CMD_SET), pt_to_str(PT_LOWER),
     1266 +                            gettext("<security flags>"));
     1267 +                        (void) fprintf(fp, "\t%s %s=%s\n",
     1268 +                            cmd_to_str(CMD_SET), pt_to_str(PT_UPPER),
     1269 +                            gettext("<security flags>"));
     1270 +                        break;
1230 1271                  }
1231 1272                  (void) fprintf(fp, gettext("And from any resource scope, you "
1232 1273                      "can:\n"));
1233 1274                  (void) fprintf(fp, "\t%s\t%s\n", cmd_to_str(CMD_END),
1234 1275                      gettext("(to conclude this operation)"));
1235 1276                  (void) fprintf(fp, "\t%s\t%s\n", cmd_to_str(CMD_CANCEL),
1236 1277                      gettext("(to cancel this operation)"));
1237 1278                  (void) fprintf(fp, "\t%s\t%s\n", cmd_to_str(CMD_EXIT),
1238 1279                      gettext("(to exit the zonecfg utility)"));
1239 1280          }
↓ open down ↓ 44 lines elided ↑ open up ↑
1284 1325                      gettext("<hostname> := [A-Za-z0-9][A-Za-z0-9-.]*\n"));
1285 1326          }
1286 1327          if (flags & HELP_RESOURCES) {
1287 1328                  (void) fprintf(fp, "<%s> := %s | %s | %s | %s | %s |\n\t"
1288 1329                      "%s | %s | %s | %s | %s\n\n",
1289 1330                      gettext("resource type"), rt_to_str(RT_FS),
1290 1331                      rt_to_str(RT_NET), rt_to_str(RT_DEVICE),
1291 1332                      rt_to_str(RT_RCTL), rt_to_str(RT_ATTR),
1292 1333                      rt_to_str(RT_DATASET), rt_to_str(RT_DCPU),
1293 1334                      rt_to_str(RT_PCAP), rt_to_str(RT_MCAP),
1294      -                    rt_to_str(RT_ADMIN));
     1335 +                    rt_to_str(RT_ADMIN), rt_to_str(RT_SECFLAGS));
1295 1336          }
1296 1337          if (flags & HELP_PROPS) {
1297 1338                  (void) fprintf(fp, gettext("For resource type ... there are "
1298 1339                      "property types ...:\n"));
1299 1340                  (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1300 1341                      pt_to_str(PT_ZONENAME));
1301 1342                  (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1302 1343                      pt_to_str(PT_ZONEPATH));
1303 1344                  (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1304 1345                      pt_to_str(PT_BRAND));
↓ open down ↓ 45 lines elided ↑ open up ↑
1350 1391                      pt_to_str(PT_NAME));
1351 1392                  (void) fprintf(fp, "\t%s\t%s, %s\n", rt_to_str(RT_DCPU),
1352 1393                      pt_to_str(PT_NCPUS), pt_to_str(PT_IMPORTANCE));
1353 1394                  (void) fprintf(fp, "\t%s\t%s\n", rt_to_str(RT_PCAP),
1354 1395                      pt_to_str(PT_NCPUS));
1355 1396                  (void) fprintf(fp, "\t%s\t%s, %s, %s\n", rt_to_str(RT_MCAP),
1356 1397                      pt_to_str(PT_PHYSICAL), pt_to_str(PT_SWAP),
1357 1398                      pt_to_str(PT_LOCKED));
1358 1399                  (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_ADMIN),
1359 1400                      pt_to_str(PT_USER), pt_to_str(PT_AUTHS));
     1401 +                (void) fprintf(fp, "\t%s\t\t%s, %s, %s\n",
     1402 +                    rt_to_str(RT_SECFLAGS), pt_to_str(PT_DEFAULT),
     1403 +                    pt_to_str(PT_LOWER), pt_to_str(PT_UPPER));
1360 1404          }
1361 1405          if (need_to_close)
1362 1406                  (void) pager_close(fp);
1363 1407  }
1364 1408  
1365 1409  static void
1366 1410  zone_perror(char *prefix, int err, boolean_t set_saw)
1367 1411  {
1368 1412          zerr("%s: %s", prefix, zonecfg_strerror(err));
1369 1413          if (set_saw)
↓ open down ↓ 423 lines elided ↑ open up ↑
1793 1837          struct zone_nwiftab nwiftab;
1794 1838          struct zone_fstab fstab;
1795 1839          struct zone_devtab devtab;
1796 1840          struct zone_attrtab attrtab;
1797 1841          struct zone_rctltab rctltab;
1798 1842          struct zone_dstab dstab;
1799 1843          struct zone_psettab psettab;
1800 1844          struct zone_mcaptab mcaptab;
1801 1845          struct zone_rctlvaltab *valptr;
1802 1846          struct zone_admintab admintab;
     1847 +        struct zone_secflagstab secflagstab;
1803 1848          int err, arg;
1804 1849          char zonepath[MAXPATHLEN], outfile[MAXPATHLEN], pool[MAXNAMELEN];
1805 1850          char bootargs[BOOTARGS_MAX];
1806 1851          char sched[MAXNAMELEN];
1807 1852          char brand[MAXNAMELEN];
1808 1853          char hostidp[HW_HOSTID_LEN];
1809 1854          char fsallowedp[ZONE_FS_ALLOWED_MAX];
1810 1855          char *limitpriv;
1811 1856          FILE *of;
1812 1857          boolean_t autoboot;
↓ open down ↓ 249 lines elided ↑ open up ↑
2062 2107                  zone_perror(zone, err, B_FALSE);
2063 2108                  goto done;
2064 2109          }
2065 2110          while (zonecfg_getadminent(handle, &admintab) == Z_OK) {
2066 2111                  (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
2067 2112                      rt_to_str(RT_ADMIN));
2068 2113                  export_prop(of, PT_USER, admintab.zone_admin_user);
2069 2114                  export_prop(of, PT_AUTHS, admintab.zone_admin_auths);
2070 2115                  (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
2071 2116          }
     2117 +
2072 2118          (void) zonecfg_endadminent(handle);
2073 2119  
     2120 +        if (zonecfg_getsecflagsent(handle, &secflagstab) == Z_OK) {
     2121 +                (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
     2122 +                    rt_to_str(RT_SECFLAGS));
     2123 +                export_prop(of, PT_DEFAULT, secflagstab.zone_secflags_default);
     2124 +                export_prop(of, PT_LOWER, secflagstab.zone_secflags_lower);
     2125 +                export_prop(of, PT_UPPER, secflagstab.zone_secflags_upper);
     2126 +                (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
     2127 +        }
     2128 +
2074 2129          /*
2075 2130           * There is nothing to export for pcap since this resource is just
2076 2131           * a container for an rctl alias.
2077 2132           */
2078 2133  
2079 2134  done:
2080 2135          if (need_to_close)
2081 2136                  (void) fclose(of);
2082 2137  }
2083 2138  
↓ open down ↓ 59 lines elided ↑ open up ↑
2143 2198          }
2144 2199          return (Z_OK);
2145 2200  }
2146 2201  
2147 2202  static void
2148 2203  add_resource(cmd_t *cmd)
2149 2204  {
2150 2205          int type;
2151 2206          struct zone_psettab tmp_psettab;
2152 2207          struct zone_mcaptab tmp_mcaptab;
     2208 +        struct zone_secflagstab tmp_secflagstab;
2153 2209          uint64_t tmp;
2154 2210          uint64_t tmp_mcap;
2155 2211          char pool[MAXNAMELEN];
2156 2212  
2157 2213          if ((type = cmd->cmd_res_type) == RT_UNKNOWN) {
2158 2214                  long_usage(CMD_ADD, B_TRUE);
2159 2215                  goto bad;
2160 2216          }
2161 2217  
2162 2218          switch (type) {
↓ open down ↓ 91 lines elided ↑ open up ↑
2254 2310                          zerr(gettext("WARNING: Setting a global zone memory "
2255 2311                              "cap too low could deny\nservice "
2256 2312                              "to even the root user; "
2257 2313                              "this could render the system impossible\n"
2258 2314                              "to administer.  Please use caution."));
2259 2315                  bzero(&in_progress_mcaptab, sizeof (in_progress_mcaptab));
2260 2316                  return;
2261 2317          case RT_ADMIN:
2262 2318                  bzero(&in_progress_admintab, sizeof (in_progress_admintab));
2263 2319                  return;
     2320 +        case RT_SECFLAGS:
     2321 +                /* Make sure we haven't already set this */
     2322 +                if (zonecfg_lookup_secflags(handle, &tmp_secflagstab) == Z_OK)
     2323 +                        zerr(gettext("The %s resource already exists."),
     2324 +                            rt_to_str(RT_SECFLAGS));
     2325 +                bzero(&in_progress_secflagstab,
     2326 +                    sizeof (in_progress_secflagstab));
     2327 +                return;
2264 2328          default:
2265 2329                  zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
2266 2330                  long_usage(CMD_ADD, B_TRUE);
2267 2331                  usage(B_FALSE, HELP_RESOURCES);
2268 2332          }
2269 2333  bad:
2270 2334          global_scope = B_TRUE;
2271 2335          end_op = -1;
2272 2336  }
2273 2337  
↓ open down ↓ 649 lines elided ↑ open up ↑
2923 2987                              Z_NO_PROPERTY_TYPE, B_TRUE);
2924 2988                          return (Z_INSUFFICIENT_SPEC);
2925 2989                  }
2926 2990          }
2927 2991          if (fill_in_only)
2928 2992                  return (Z_OK);
2929 2993          err = zonecfg_lookup_admin(handle, admintab);
2930 2994          return (err);
2931 2995  }
2932 2996  
     2997 +static int
     2998 +fill_in_secflagstab(cmd_t *cmd, struct zone_secflagstab *secflagstab,
     2999 +    boolean_t fill_in_only)
     3000 +{
     3001 +        int err, i;
     3002 +        property_value_ptr_t pp;
     3003 +
     3004 +        if ((err = initialize(B_TRUE)) != Z_OK)
     3005 +                return (err);
     3006 +
     3007 +        bzero(secflagstab, sizeof (*secflagstab));
     3008 +        for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
     3009 +                pp = cmd->cmd_property_ptr[i];
     3010 +                if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
     3011 +                        zerr(gettext("A simple value was expected here."));
     3012 +                        saw_error = B_TRUE;
     3013 +                        return (Z_INSUFFICIENT_SPEC);
     3014 +                }
     3015 +                switch (cmd->cmd_prop_name[i]) {
     3016 +                case PT_DEFAULT:
     3017 +                        (void) strlcpy(secflagstab->zone_secflags_default,
     3018 +                            pp->pv_simple,
     3019 +                            sizeof (secflagstab->zone_secflags_default));
     3020 +                        break;
     3021 +                case PT_LOWER:
     3022 +                        (void) strlcpy(secflagstab->zone_secflags_lower,
     3023 +                            pp->pv_simple,
     3024 +                            sizeof (secflagstab->zone_secflags_lower));
     3025 +                        break;
     3026 +                case PT_UPPER:
     3027 +                        (void) strlcpy(secflagstab->zone_secflags_upper,
     3028 +                            pp->pv_simple,
     3029 +                            sizeof (secflagstab->zone_secflags_upper));
     3030 +                        break;
     3031 +                default:
     3032 +                        zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
     3033 +                            Z_NO_PROPERTY_TYPE, B_TRUE);
     3034 +                        return (Z_INSUFFICIENT_SPEC);
     3035 +                }
     3036 +        }
     3037 +        if (fill_in_only)
     3038 +                return (Z_OK);
     3039 +
     3040 +        err = zonecfg_lookup_secflags(handle, secflagstab);
     3041 +
     3042 +        return (err);
     3043 +}
     3044 +
2933 3045  static void
2934 3046  remove_aliased_rctl(int type, char *name)
2935 3047  {
2936 3048          int err;
2937 3049          uint64_t tmp;
2938 3050  
2939 3051          if ((err = zonecfg_get_aliased_rctl(handle, name, &tmp)) != Z_OK) {
2940 3052                  zerr("%s %s: %s", cmd_to_str(CMD_CLEAR), pt_to_str(type),
2941 3053                      zonecfg_strerror(err));
2942 3054                  saw_error = B_TRUE;
↓ open down ↓ 382 lines elided ↑ open up ↑
3325 3437                  if ((err = zonecfg_delete_admins(handle, zone))
3326 3438                      != Z_OK)
3327 3439                          z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN,
3328 3440                              err, B_TRUE);
3329 3441                  else
3330 3442                          need_to_commit = B_TRUE;
3331 3443          }
3332 3444  }
3333 3445  
3334 3446  static void
     3447 +remove_secflags()
     3448 +{
     3449 +        int err;
     3450 +        struct zone_secflagstab sectab = { 0 };
     3451 +
     3452 +        if (zonecfg_lookup_secflags(handle, &sectab) != Z_OK) {
     3453 +                zerr("%s %s: %s", cmd_to_str(CMD_REMOVE),
     3454 +                    rt_to_str(RT_SECFLAGS),
     3455 +                    zonecfg_strerror(Z_NO_RESOURCE_TYPE));
     3456 +                return;
     3457 +        }
     3458 +
     3459 +        if ((err = zonecfg_delete_secflags(handle, &sectab)) != Z_OK) {
     3460 +                z_cmd_rt_perror(CMD_REMOVE, RT_SECFLAGS, err, B_TRUE);
     3461 +                return;
     3462 +        }
     3463 +
     3464 +        need_to_commit = B_TRUE;
     3465 +}
     3466 +
     3467 +static void
3335 3468  remove_resource(cmd_t *cmd)
3336 3469  {
3337 3470          int type;
3338 3471          int arg;
3339 3472          boolean_t arg_err = B_FALSE;
3340 3473  
3341 3474          if ((type = cmd->cmd_res_type) == RT_UNKNOWN) {
3342 3475                  long_usage(CMD_REMOVE, B_TRUE);
3343 3476                  return;
3344 3477          }
↓ open down ↓ 43 lines elided ↑ open up ↑
3388 3521                  return;
3389 3522          case RT_PCAP:
3390 3523                  remove_pcap();
3391 3524                  return;
3392 3525          case RT_MCAP:
3393 3526                  remove_mcap();
3394 3527                  return;
3395 3528          case RT_ADMIN:
3396 3529                  remove_admin(cmd);
3397 3530                  return;
     3531 +        case RT_SECFLAGS:
     3532 +                remove_secflags();
     3533 +                return;
3398 3534          default:
3399 3535                  zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
3400 3536                  long_usage(CMD_REMOVE, B_TRUE);
3401 3537                  usage(B_FALSE, HELP_RESOURCES);
3402 3538                  return;
3403 3539          }
3404 3540  }
3405 3541  
3406 3542  static void
3407 3543  remove_property(cmd_t *cmd)
↓ open down ↓ 192 lines elided ↑ open up ↑
3600 3736                          need_to_commit = B_TRUE;
3601 3737                          return;
3602 3738                  case PT_SWAP:
3603 3739                          remove_aliased_rctl(PT_SWAP, ALIAS_MAXSWAP);
3604 3740                          return;
3605 3741                  case PT_LOCKED:
3606 3742                          remove_aliased_rctl(PT_LOCKED, ALIAS_MAXLOCKEDMEM);
3607 3743                          return;
3608 3744                  }
3609 3745                  break;
     3746 +        case RT_SECFLAGS:
     3747 +                switch (prop_type) {
     3748 +                case PT_LOWER:
     3749 +                        in_progress_secflagstab.zone_secflags_lower[0] = '\0';
     3750 +                        need_to_commit = B_TRUE;
     3751 +                        return;
     3752 +                case PT_DEFAULT:
     3753 +                        in_progress_secflagstab.zone_secflags_default[0] = '\0';
     3754 +                        need_to_commit = B_TRUE;
     3755 +                        return;
     3756 +                case PT_UPPER:
     3757 +                        in_progress_secflagstab.zone_secflags_upper[0] = '\0';
     3758 +                        need_to_commit = B_TRUE;
     3759 +                        return;
     3760 +                }
     3761 +                break;
3610 3762          default:
3611 3763                  break;
3612 3764          }
3613 3765  
3614 3766          zone_perror(pt_to_str(prop_type), Z_CLEAR_DISALLOW, B_TRUE);
3615 3767  }
3616 3768  
3617 3769  static void
3618 3770  clear_global(cmd_t *cmd)
3619 3771  {
↓ open down ↓ 233 lines elided ↑ open up ↑
3853 4005          case RT_ADMIN:
3854 4006                  if ((err = fill_in_admintab(cmd, &old_admintab, B_FALSE))
3855 4007                      != Z_OK) {
3856 4008                          z_cmd_rt_perror(CMD_SELECT, RT_ADMIN, err,
3857 4009                              B_TRUE);
3858 4010                          global_scope = B_TRUE;
3859 4011                  }
3860 4012                  bcopy(&old_admintab, &in_progress_admintab,
3861 4013                      sizeof (struct zone_admintab));
3862 4014                  return;
     4015 +        case RT_SECFLAGS:
     4016 +                if ((err = fill_in_secflagstab(cmd, &old_secflagstab, B_FALSE))
     4017 +                    != Z_OK) {
     4018 +                        z_cmd_rt_perror(CMD_SELECT, RT_SECFLAGS, err,
     4019 +                            B_TRUE);
     4020 +                        global_scope = B_TRUE;
     4021 +                }
     4022 +                bcopy(&old_secflagstab, &in_progress_secflagstab,
     4023 +                    sizeof (struct zone_secflagstab));
     4024 +                return;
3863 4025          default:
3864 4026                  zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
3865 4027                  long_usage(CMD_SELECT, B_TRUE);
3866 4028                  usage(B_FALSE, HELP_RESOURCES);
3867 4029                  return;
3868 4030          }
3869 4031  }
3870 4032  
3871 4033  /*
3872 4034   * Network "addresses" can be one of the following forms:
↓ open down ↓ 896 lines elided ↑ open up ↑
4769 4931                              prop_id,
4770 4932                              sizeof (in_progress_admintab.zone_admin_auths));
4771 4933                          return;
4772 4934                  default:
4773 4935                          zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4774 4936                              B_TRUE);
4775 4937                          long_usage(CMD_SET, B_TRUE);
4776 4938                          usage(B_FALSE, HELP_PROPS);
4777 4939                          return;
4778 4940                  }
     4941 +        case RT_SECFLAGS: {
     4942 +                char *propstr;
     4943 +
     4944 +                switch (prop_type) {
     4945 +                case PT_DEFAULT:
     4946 +                        propstr = in_progress_secflagstab.zone_secflags_default;
     4947 +                        break;
     4948 +                case PT_UPPER:
     4949 +                        propstr = in_progress_secflagstab.zone_secflags_upper;
     4950 +                        break;
     4951 +                case PT_LOWER:
     4952 +                        propstr = in_progress_secflagstab.zone_secflags_lower;
     4953 +                        break;
     4954 +                default:
     4955 +                        zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
     4956 +                            B_TRUE);
     4957 +                        long_usage(CMD_SET, B_TRUE);
     4958 +                        usage(B_FALSE, HELP_PROPS);
     4959 +                        return;
     4960 +                }
     4961 +                (void) strlcpy(propstr, prop_id, ZONECFG_SECFLAGS_MAX);
     4962 +                return;
     4963 +        }
4779 4964          default:
4780 4965                  zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, B_TRUE);
4781 4966                  long_usage(CMD_SET, B_TRUE);
4782 4967                  usage(B_FALSE, HELP_RESOURCES);
4783 4968                  return;
4784 4969          }
4785 4970  }
4786 4971  
4787 4972  static void
4788 4973  output_prop(FILE *fp, int pnum, char *pval, boolean_t print_notspec)
↓ open down ↓ 594 lines elided ↑ open up ↑
5383 5568  
5384 5569  static void
5385 5570  output_auth(FILE *fp, struct zone_admintab *admintab)
5386 5571  {
5387 5572          (void) fprintf(fp, "%s:\n", rt_to_str(RT_ADMIN));
5388 5573          output_prop(fp, PT_USER, admintab->zone_admin_user, B_TRUE);
5389 5574          output_prop(fp, PT_AUTHS, admintab->zone_admin_auths, B_TRUE);
5390 5575  }
5391 5576  
5392 5577  static void
     5578 +output_secflags(FILE *fp, struct zone_secflagstab *sftab)
     5579 +{
     5580 +        (void) fprintf(fp, "%s:\n", rt_to_str(RT_SECFLAGS));
     5581 +        output_prop(fp, PT_DEFAULT, sftab->zone_secflags_default, B_TRUE);
     5582 +        output_prop(fp, PT_LOWER, sftab->zone_secflags_lower, B_TRUE);
     5583 +        output_prop(fp, PT_UPPER, sftab->zone_secflags_upper, B_TRUE);
     5584 +}
     5585 +
     5586 +static void
5393 5587  info_auth(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5394 5588  {
5395 5589          struct zone_admintab lookup, user;
5396 5590          boolean_t output = B_FALSE;
5397 5591          int err;
5398 5592  
5399 5593          if ((err = zonecfg_setadminent(handle)) != Z_OK) {
5400 5594                  zone_perror(zone, err, B_TRUE);
5401 5595                  return;
5402 5596          }
↓ open down ↓ 13 lines elided ↑ open up ↑
5416 5610          (void) zonecfg_endadminent(handle);
5417 5611          /*
5418 5612           * If a property n/v pair was specified, warn the user if there was
5419 5613           * nothing to output.
5420 5614           */
5421 5615          if (!output && cmd->cmd_prop_nv_pairs > 0)
5422 5616                  (void) printf(gettext("No such %s resource.\n"),
5423 5617                      rt_to_str(RT_ADMIN));
5424 5618  }
5425 5619  
     5620 +static void
     5621 +info_secflags(zone_dochandle_t handle, FILE *fp)
     5622 +{
     5623 +        struct zone_secflagstab sftab;
     5624 +
     5625 +        if (zonecfg_lookup_secflags(handle, &sftab) == Z_OK) {
     5626 +                output_secflags(fp, &sftab);
     5627 +        }
     5628 +}
     5629 +
5426 5630  void
5427 5631  info_func(cmd_t *cmd)
5428 5632  {
5429 5633          FILE *fp = stdout;
5430 5634          boolean_t need_to_close = B_FALSE;
5431 5635          int type;
5432 5636          int res1, res2;
5433 5637          uint64_t swap_limit;
5434 5638          uint64_t locked_limit;
5435 5639  
↓ open down ↓ 42 lines elided ↑ open up ↑
5478 5682                          res1 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP,
5479 5683                              &swap_limit);
5480 5684                          res2 = zonecfg_get_aliased_rctl(handle,
5481 5685                              ALIAS_MAXLOCKEDMEM, &locked_limit);
5482 5686                          output_mcap(fp, &in_progress_mcaptab, res1, swap_limit,
5483 5687                              res2, locked_limit);
5484 5688                          break;
5485 5689                  case RT_ADMIN:
5486 5690                          output_auth(fp, &in_progress_admintab);
5487 5691                          break;
     5692 +                case RT_SECFLAGS:
     5693 +                        output_secflags(fp, &in_progress_secflagstab);
     5694 +                        break;
5488 5695                  }
5489 5696                  goto cleanup;
5490 5697          }
5491 5698  
5492 5699          type = cmd->cmd_res_type;
5493 5700  
5494 5701          if (gz_invalid_rt_property(type)) {
5495 5702                  zerr(gettext("%s is not a valid property for the global zone."),
5496 5703                      rt_to_str(type));
5497 5704                  goto cleanup;
↓ open down ↓ 36 lines elided ↑ open up ↑
5534 5741                  }
5535 5742                  info_pset(handle, fp);
5536 5743                  info_pcap(fp);
5537 5744                  info_mcap(handle, fp);
5538 5745                  if (!global_zone) {
5539 5746                          info_attr(handle, fp, cmd);
5540 5747                          info_ds(handle, fp, cmd);
5541 5748                          info_auth(handle, fp, cmd);
5542 5749                  }
5543 5750                  info_rctl(handle, fp, cmd);
     5751 +                info_secflags(handle, fp);
5544 5752                  break;
5545 5753          case RT_ZONENAME:
5546 5754                  info_zonename(handle, fp);
5547 5755                  break;
5548 5756          case RT_ZONEPATH:
5549 5757                  info_zonepath(handle, fp);
5550 5758                  break;
5551 5759          case RT_BRAND:
5552 5760                  info_brand(handle, fp);
5553 5761                  break;
↓ open down ↓ 65 lines elided ↑ open up ↑
5619 5827                  break;
5620 5828          case RT_HOSTID:
5621 5829                  info_hostid(handle, fp);
5622 5830                  break;
5623 5831          case RT_ADMIN:
5624 5832                  info_auth(handle, fp, cmd);
5625 5833                  break;
5626 5834          case RT_FS_ALLOWED:
5627 5835                  info_fs_allowed(handle, fp);
5628 5836                  break;
     5837 +        case RT_SECFLAGS:
     5838 +                info_secflags(handle, fp);
     5839 +                break;
5629 5840          default:
5630 5841                  zone_perror(rt_to_str(cmd->cmd_res_type), Z_NO_RESOURCE_TYPE,
5631 5842                      B_TRUE);
5632 5843          }
5633 5844  
5634 5845  cleanup:
5635 5846          if (need_to_close)
5636 5847                  (void) pager_close(fp);
5637 5848  }
5638 5849  
↓ open down ↓ 131 lines elided ↑ open up ↑
5770 5981          }
5771 5982          strlcpy(tmp->xif_name, nwif->zone_nwif_physical,
5772 5983              sizeof (tmp->xif_name));
5773 5984          tmp->xif_has_defrouter = (strlen(nwif->zone_nwif_defrouter) > 0);
5774 5985          tmp->xif_has_address = (strlen(nwif->zone_nwif_allowed_address) > 0);
5775 5986          tmp->xif_next = xif;
5776 5987          xif = tmp;
5777 5988          return (B_TRUE);
5778 5989  }
5779 5990  
     5991 +boolean_t
     5992 +verify_secflags(struct zone_secflagstab *tab)
     5993 +{
     5994 +        secflagdelta_t def = {0};
     5995 +        secflagdelta_t upper = {0};
     5996 +        secflagdelta_t lower = {0};
     5997 +        boolean_t def_set = B_FALSE;
     5998 +        boolean_t upper_set = B_FALSE;
     5999 +        boolean_t lower_set = B_FALSE;
     6000 +        boolean_t ret = B_TRUE;
     6001 +
     6002 +        if (strlen(tab->zone_secflags_default) > 0) {
     6003 +                def_set = B_TRUE;
     6004 +                if (secflags_parse(NULL, tab->zone_secflags_default,
     6005 +                    &def) == -1) {
     6006 +                        zerr(gettext("default security flags '%s' are invalid"),
     6007 +                            tab->zone_secflags_default);
     6008 +                        ret = B_FALSE;
     6009 +                }
     6010 +        } else {
     6011 +                secflags_zero(&def.psd_assign);
     6012 +                def.psd_ass_active = B_TRUE;
     6013 +        }
     6014 +
     6015 +        if (strlen(tab->zone_secflags_upper) > 0) {
     6016 +                upper_set = B_TRUE;
     6017 +                if (secflags_parse(NULL, tab->zone_secflags_upper,
     6018 +                    &upper) == -1) {
     6019 +                        zerr(gettext("upper security flags '%s' are invalid"),
     6020 +                            tab->zone_secflags_upper);
     6021 +                        ret = B_FALSE;
     6022 +                }
     6023 +        } else {
     6024 +                secflags_fullset(&upper.psd_assign);
     6025 +                upper.psd_ass_active = B_TRUE;
     6026 +        }
     6027 +
     6028 +        if (strlen(tab->zone_secflags_lower) > 0) {
     6029 +                lower_set = B_TRUE;
     6030 +                if (secflags_parse(NULL, tab->zone_secflags_lower,
     6031 +                    &lower) == -1) {
     6032 +                        zerr(gettext("lower security flags '%s' are invalid"),
     6033 +                            tab->zone_secflags_lower);
     6034 +                        ret = B_FALSE;
     6035 +                }
     6036 +        } else {
     6037 +                secflags_zero(&lower.psd_assign);
     6038 +                lower.psd_ass_active = B_TRUE;
     6039 +        }
     6040 +
     6041 +        if (def_set && !def.psd_ass_active) {
     6042 +                zerr(gettext("only assignment of security flags is "
     6043 +                    "allowed (default: %s)"), tab->zone_secflags_default);
     6044 +        }
     6045 +
     6046 +        if (lower_set && !lower.psd_ass_active) {
     6047 +                zerr(gettext("only assignment of security flags is "
     6048 +                    "allowed (lower: %s)"), tab->zone_secflags_lower);
     6049 +        }
     6050 +
     6051 +        if (upper_set && !upper.psd_ass_active) {
     6052 +                zerr(gettext("only assignment of security flags is "
     6053 +                    "allowed (upper: %s)"), tab->zone_secflags_upper);
     6054 +        }
     6055 +
     6056 +        if (def.psd_assign & ~upper.psd_assign) { /* In default but not upper */
     6057 +                zerr(gettext("default secflags must be within the "
     6058 +                    "upper limit"));
     6059 +                ret = B_FALSE;
     6060 +        }
     6061 +        if (lower.psd_assign & ~def.psd_assign) { /* In lower but not default */
     6062 +                zerr(gettext("default secflags must be above the lower limit"));
     6063 +                ret = B_FALSE;
     6064 +        }
     6065 +        if (lower.psd_assign & ~upper.psd_assign) { /* In lower but not upper */
     6066 +                zerr(gettext("lower secflags must be within the upper limit"));
     6067 +                ret = B_FALSE;
     6068 +        }
     6069 +
     6070 +        return (ret);
     6071 +}
     6072 +
5780 6073  /*
5781 6074   * See the DTD for which attributes are required for which resources.
5782 6075   *
5783 6076   * This function can be called by commit_func(), which needs to save things,
5784 6077   * in addition to the general call from parse_and_run(), which doesn't need
5785 6078   * things saved.  Since the parameters are standardized, we distinguish by
5786 6079   * having commit_func() call here with cmd->cmd_arg set to "save" to indicate
5787 6080   * that a save is needed.
5788 6081   */
5789 6082  void
5790 6083  verify_func(cmd_t *cmd)
5791 6084  {
5792 6085          struct zone_nwiftab nwiftab;
5793 6086          struct zone_fstab fstab;
5794 6087          struct zone_attrtab attrtab;
5795 6088          struct zone_rctltab rctltab;
5796 6089          struct zone_dstab dstab;
5797 6090          struct zone_psettab psettab;
5798 6091          struct zone_admintab admintab;
     6092 +        struct zone_secflagstab secflagstab;
5799 6093          char zonepath[MAXPATHLEN];
5800 6094          char sched[MAXNAMELEN];
5801 6095          char brand[MAXNAMELEN];
5802 6096          char hostidp[HW_HOSTID_LEN];
5803 6097          char fsallowedp[ZONE_FS_ALLOWED_MAX];
5804 6098          priv_set_t *privs;
5805 6099          char *privname = NULL;
5806 6100          int err, ret_val = Z_OK, arg;
5807 6101          int pset_res;
5808 6102          boolean_t save = B_FALSE;
↓ open down ↓ 276 lines elided ↑ open up ↑
6085 6379                              admintab.zone_admin_user);
6086 6380                          ret_val = Z_BAD_PROPERTY;
6087 6381                  }
6088 6382                  if ((ret_val == Z_OK) && (!zonecfg_valid_auths(
6089 6383                      admintab.zone_admin_auths, zone))) {
6090 6384                          ret_val = Z_BAD_PROPERTY;
6091 6385                  }
6092 6386          }
6093 6387          (void) zonecfg_endadminent(handle);
6094 6388  
     6389 +        if (zonecfg_getsecflagsent(handle, &secflagstab) == Z_OK) {
     6390 +                /*
     6391 +                 * No properties are required, but any specified should be
     6392 +                 * valid
     6393 +                 */
     6394 +                if (verify_secflags(&secflagstab) != B_TRUE) {
     6395 +                        /* Error is reported from verify_secflags */
     6396 +                        ret_val = Z_BAD_PROPERTY;
     6397 +                }
     6398 +        }
     6399 +
6095 6400          if (!global_scope) {
6096 6401                  zerr(gettext("resource specification incomplete"));
6097 6402                  saw_error = B_TRUE;
6098 6403                  if (ret_val == Z_OK)
6099 6404                          ret_val = Z_INSUFFICIENT_SPEC;
6100 6405          }
6101 6406  
6102 6407          if (save) {
6103 6408                  if (ret_val == Z_OK) {
6104 6409                          if ((ret_val = zonecfg_save(handle)) == Z_OK) {
↓ open down ↓ 569 lines elided ↑ open up ↑
6674 6979                                  return;
6675 6980                          }
6676 6981                          err = zonecfg_add_admin(handle,
6677 6982                              &in_progress_admintab, zone);
6678 6983                  } else {
6679 6984                          err = zonecfg_modify_admin(handle,
6680 6985                              &old_admintab, &in_progress_admintab,
6681 6986                              zone);
6682 6987                  }
6683 6988                  break;
     6989 +        case RT_SECFLAGS:
     6990 +                if (verify_secflags(&in_progress_secflagstab) != B_TRUE) {
     6991 +                        saw_error = B_TRUE;
     6992 +                        return;
     6993 +                }
     6994 +
     6995 +                if (end_op == CMD_ADD) {
     6996 +                        err = zonecfg_add_secflags(handle,
     6997 +                            &in_progress_secflagstab);
     6998 +                } else {
     6999 +                        err = zonecfg_modify_secflags(handle,
     7000 +                            &old_secflagstab, &in_progress_secflagstab);
     7001 +                }
     7002 +                break;
6684 7003          default:
6685 7004                  zone_perror(rt_to_str(resource_scope), Z_NO_RESOURCE_TYPE,
6686 7005                      B_TRUE);
6687 7006                  saw_error = B_TRUE;
6688 7007                  return;
6689 7008          }
6690 7009  
6691 7010          if (err != Z_OK) {
6692 7011                  zone_perror(zone, err, B_TRUE);
6693 7012          } else {
↓ open down ↓ 607 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX