Print this page
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 ((err = zonecfg_getsecflagsent(handle, &secflagstab)) != Z_OK) {
     2121 +                zone_perror(zone, err, B_FALSE);
     2122 +                goto done;
     2123 +        }
     2124 +
     2125 +        (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
     2126 +            rt_to_str(RT_SECFLAGS));
     2127 +        export_prop(of, PT_DEFAULT, secflagstab.zone_secflags_default);
     2128 +        export_prop(of, PT_LOWER, secflagstab.zone_secflags_lower);
     2129 +        export_prop(of, PT_UPPER, secflagstab.zone_secflags_upper);
     2130 +        (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
     2131 +
2074 2132          /*
2075 2133           * There is nothing to export for pcap since this resource is just
2076 2134           * a container for an rctl alias.
2077 2135           */
2078 2136  
2079 2137  done:
2080 2138          if (need_to_close)
2081 2139                  (void) fclose(of);
2082 2140  }
2083 2141  
↓ open down ↓ 59 lines elided ↑ open up ↑
2143 2201          }
2144 2202          return (Z_OK);
2145 2203  }
2146 2204  
2147 2205  static void
2148 2206  add_resource(cmd_t *cmd)
2149 2207  {
2150 2208          int type;
2151 2209          struct zone_psettab tmp_psettab;
2152 2210          struct zone_mcaptab tmp_mcaptab;
     2211 +        struct zone_secflagstab tmp_secflagstab;
2153 2212          uint64_t tmp;
2154 2213          uint64_t tmp_mcap;
2155 2214          char pool[MAXNAMELEN];
2156 2215  
2157 2216          if ((type = cmd->cmd_res_type) == RT_UNKNOWN) {
2158 2217                  long_usage(CMD_ADD, B_TRUE);
2159 2218                  goto bad;
2160 2219          }
2161 2220  
2162 2221          switch (type) {
↓ open down ↓ 91 lines elided ↑ open up ↑
2254 2313                          zerr(gettext("WARNING: Setting a global zone memory "
2255 2314                              "cap too low could deny\nservice "
2256 2315                              "to even the root user; "
2257 2316                              "this could render the system impossible\n"
2258 2317                              "to administer.  Please use caution."));
2259 2318                  bzero(&in_progress_mcaptab, sizeof (in_progress_mcaptab));
2260 2319                  return;
2261 2320          case RT_ADMIN:
2262 2321                  bzero(&in_progress_admintab, sizeof (in_progress_admintab));
2263 2322                  return;
     2323 +        case RT_SECFLAGS:
     2324 +                /* Make sure we haven't already set this */
     2325 +                if (zonecfg_lookup_secflags(handle, &tmp_secflagstab) == Z_OK)
     2326 +                        zerr(gettext("The %s resource already exists."),
     2327 +                            rt_to_str(RT_SECFLAGS));
     2328 +                bzero(&in_progress_secflagstab,
     2329 +                    sizeof (in_progress_secflagstab));
     2330 +                return;
2264 2331          default:
2265 2332                  zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
2266 2333                  long_usage(CMD_ADD, B_TRUE);
2267 2334                  usage(B_FALSE, HELP_RESOURCES);
2268 2335          }
2269 2336  bad:
2270 2337          global_scope = B_TRUE;
2271 2338          end_op = -1;
2272 2339  }
2273 2340  
↓ open down ↓ 649 lines elided ↑ open up ↑
2923 2990                              Z_NO_PROPERTY_TYPE, B_TRUE);
2924 2991                          return (Z_INSUFFICIENT_SPEC);
2925 2992                  }
2926 2993          }
2927 2994          if (fill_in_only)
2928 2995                  return (Z_OK);
2929 2996          err = zonecfg_lookup_admin(handle, admintab);
2930 2997          return (err);
2931 2998  }
2932 2999  
     3000 +static int
     3001 +fill_in_secflagstab(cmd_t *cmd, struct zone_secflagstab *secflagstab,
     3002 +    boolean_t fill_in_only)
     3003 +{
     3004 +        int err, i;
     3005 +        property_value_ptr_t pp;
     3006 +
     3007 +        if ((err = initialize(B_TRUE)) != Z_OK)
     3008 +                return (err);
     3009 +
     3010 +        bzero(secflagstab, sizeof (*secflagstab));
     3011 +        for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
     3012 +                pp = cmd->cmd_property_ptr[i];
     3013 +                if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
     3014 +                        zerr(gettext("A simple value was expected here."));
     3015 +                        saw_error = B_TRUE;
     3016 +                        return (Z_INSUFFICIENT_SPEC);
     3017 +                }
     3018 +                switch (cmd->cmd_prop_name[i]) {
     3019 +                case PT_DEFAULT:
     3020 +                        (void) strlcpy(secflagstab->zone_secflags_default,
     3021 +                            pp->pv_simple,
     3022 +                            sizeof (secflagstab->zone_secflags_default));
     3023 +                        break;
     3024 +                case PT_LOWER:
     3025 +                        (void) strlcpy(secflagstab->zone_secflags_lower,
     3026 +                            pp->pv_simple,
     3027 +                            sizeof (secflagstab->zone_secflags_lower));
     3028 +                        break;
     3029 +                case PT_UPPER:
     3030 +                        (void) strlcpy(secflagstab->zone_secflags_upper,
     3031 +                            pp->pv_simple,
     3032 +                            sizeof (secflagstab->zone_secflags_upper));
     3033 +                        break;
     3034 +                default:
     3035 +                        zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
     3036 +                            Z_NO_PROPERTY_TYPE, B_TRUE);
     3037 +                        return (Z_INSUFFICIENT_SPEC);
     3038 +                }
     3039 +        }
     3040 +        if (fill_in_only)
     3041 +                return (Z_OK);
     3042 +
     3043 +        err = zonecfg_lookup_secflags(handle, secflagstab);
     3044 +
     3045 +        return (err);
     3046 +}
     3047 +
2933 3048  static void
2934 3049  remove_aliased_rctl(int type, char *name)
2935 3050  {
2936 3051          int err;
2937 3052          uint64_t tmp;
2938 3053  
2939 3054          if ((err = zonecfg_get_aliased_rctl(handle, name, &tmp)) != Z_OK) {
2940 3055                  zerr("%s %s: %s", cmd_to_str(CMD_CLEAR), pt_to_str(type),
2941 3056                      zonecfg_strerror(err));
2942 3057                  saw_error = B_TRUE;
↓ open down ↓ 382 lines elided ↑ open up ↑
3325 3440                  if ((err = zonecfg_delete_admins(handle, zone))
3326 3441                      != Z_OK)
3327 3442                          z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN,
3328 3443                              err, B_TRUE);
3329 3444                  else
3330 3445                          need_to_commit = B_TRUE;
3331 3446          }
3332 3447  }
3333 3448  
3334 3449  static void
     3450 +remove_secflags()
     3451 +{
     3452 +        int err;
     3453 +        struct zone_secflagstab sectab = { 0 };
     3454 +
     3455 +        if (zonecfg_lookup_secflags(handle, &sectab) != Z_OK) {
     3456 +                zerr("%s %s: %s", cmd_to_str(CMD_REMOVE),
     3457 +                    rt_to_str(RT_SECFLAGS),
     3458 +                    zonecfg_strerror(Z_NO_RESOURCE_TYPE));
     3459 +                return;
     3460 +        }
     3461 +
     3462 +        if ((err = zonecfg_delete_secflags(handle, &sectab)) != Z_OK) {
     3463 +                z_cmd_rt_perror(CMD_REMOVE, RT_SECFLAGS, err, B_TRUE);
     3464 +                return;
     3465 +        }
     3466 +
     3467 +        need_to_commit = B_TRUE;
     3468 +}
     3469 +
     3470 +static void
3335 3471  remove_resource(cmd_t *cmd)
3336 3472  {
3337 3473          int type;
3338 3474          int arg;
3339 3475          boolean_t arg_err = B_FALSE;
3340 3476  
3341 3477          if ((type = cmd->cmd_res_type) == RT_UNKNOWN) {
3342 3478                  long_usage(CMD_REMOVE, B_TRUE);
3343 3479                  return;
3344 3480          }
↓ open down ↓ 43 lines elided ↑ open up ↑
3388 3524                  return;
3389 3525          case RT_PCAP:
3390 3526                  remove_pcap();
3391 3527                  return;
3392 3528          case RT_MCAP:
3393 3529                  remove_mcap();
3394 3530                  return;
3395 3531          case RT_ADMIN:
3396 3532                  remove_admin(cmd);
3397 3533                  return;
     3534 +        case RT_SECFLAGS:
     3535 +                remove_secflags();
     3536 +                return;
3398 3537          default:
3399 3538                  zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
3400 3539                  long_usage(CMD_REMOVE, B_TRUE);
3401 3540                  usage(B_FALSE, HELP_RESOURCES);
3402 3541                  return;
3403 3542          }
3404 3543  }
3405 3544  
3406 3545  static void
3407 3546  remove_property(cmd_t *cmd)
↓ open down ↓ 192 lines elided ↑ open up ↑
3600 3739                          need_to_commit = B_TRUE;
3601 3740                          return;
3602 3741                  case PT_SWAP:
3603 3742                          remove_aliased_rctl(PT_SWAP, ALIAS_MAXSWAP);
3604 3743                          return;
3605 3744                  case PT_LOCKED:
3606 3745                          remove_aliased_rctl(PT_LOCKED, ALIAS_MAXLOCKEDMEM);
3607 3746                          return;
3608 3747                  }
3609 3748                  break;
     3749 +        case RT_SECFLAGS:
     3750 +                switch (prop_type) {
     3751 +                case PT_LOWER:
     3752 +                        in_progress_secflagstab.zone_secflags_lower[0] = '\0';
     3753 +                        need_to_commit = B_TRUE;
     3754 +                        return;
     3755 +                case PT_DEFAULT:
     3756 +                        in_progress_secflagstab.zone_secflags_default[0] = '\0';
     3757 +                        need_to_commit = B_TRUE;
     3758 +                        return;
     3759 +                case PT_UPPER:
     3760 +                        in_progress_secflagstab.zone_secflags_upper[0] = '\0';
     3761 +                        need_to_commit = B_TRUE;
     3762 +                        return;
     3763 +                }
     3764 +                break;
3610 3765          default:
3611 3766                  break;
3612 3767          }
3613 3768  
3614 3769          zone_perror(pt_to_str(prop_type), Z_CLEAR_DISALLOW, B_TRUE);
3615 3770  }
3616 3771  
3617 3772  static void
3618 3773  clear_global(cmd_t *cmd)
3619 3774  {
↓ open down ↓ 233 lines elided ↑ open up ↑
3853 4008          case RT_ADMIN:
3854 4009                  if ((err = fill_in_admintab(cmd, &old_admintab, B_FALSE))
3855 4010                      != Z_OK) {
3856 4011                          z_cmd_rt_perror(CMD_SELECT, RT_ADMIN, err,
3857 4012                              B_TRUE);
3858 4013                          global_scope = B_TRUE;
3859 4014                  }
3860 4015                  bcopy(&old_admintab, &in_progress_admintab,
3861 4016                      sizeof (struct zone_admintab));
3862 4017                  return;
     4018 +        case RT_SECFLAGS:
     4019 +                if ((err = fill_in_secflagstab(cmd, &old_secflagstab, B_FALSE))
     4020 +                    != Z_OK) {
     4021 +                        z_cmd_rt_perror(CMD_SELECT, RT_SECFLAGS, err,
     4022 +                            B_TRUE);
     4023 +                        global_scope = B_TRUE;
     4024 +                }
     4025 +                bcopy(&old_secflagstab, &in_progress_secflagstab,
     4026 +                    sizeof (struct zone_secflagstab));
     4027 +                return;
3863 4028          default:
3864 4029                  zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
3865 4030                  long_usage(CMD_SELECT, B_TRUE);
3866 4031                  usage(B_FALSE, HELP_RESOURCES);
3867 4032                  return;
3868 4033          }
3869 4034  }
3870 4035  
3871 4036  /*
3872 4037   * Network "addresses" can be one of the following forms:
↓ open down ↓ 896 lines elided ↑ open up ↑
4769 4934                              prop_id,
4770 4935                              sizeof (in_progress_admintab.zone_admin_auths));
4771 4936                          return;
4772 4937                  default:
4773 4938                          zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4774 4939                              B_TRUE);
4775 4940                          long_usage(CMD_SET, B_TRUE);
4776 4941                          usage(B_FALSE, HELP_PROPS);
4777 4942                          return;
4778 4943                  }
     4944 +        case RT_SECFLAGS: {
     4945 +                char *propstr;
     4946 +
     4947 +                switch (prop_type) {
     4948 +                case PT_DEFAULT:
     4949 +                        propstr = in_progress_secflagstab.zone_secflags_default;
     4950 +                        break;
     4951 +                case PT_UPPER:
     4952 +                        propstr = in_progress_secflagstab.zone_secflags_upper;
     4953 +                        break;
     4954 +                case PT_LOWER:
     4955 +                        propstr = in_progress_secflagstab.zone_secflags_lower;
     4956 +                        break;
     4957 +                default:
     4958 +                        zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
     4959 +                            B_TRUE);
     4960 +                        long_usage(CMD_SET, B_TRUE);
     4961 +                        usage(B_FALSE, HELP_PROPS);
     4962 +                        return;
     4963 +                }
     4964 +                (void) strlcpy(propstr, prop_id, ZONECFG_SECFLAGS_MAX);
     4965 +                return;
     4966 +        }
4779 4967          default:
4780 4968                  zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, B_TRUE);
4781 4969                  long_usage(CMD_SET, B_TRUE);
4782 4970                  usage(B_FALSE, HELP_RESOURCES);
4783 4971                  return;
4784 4972          }
4785 4973  }
4786 4974  
4787 4975  static void
4788 4976  output_prop(FILE *fp, int pnum, char *pval, boolean_t print_notspec)
↓ open down ↓ 594 lines elided ↑ open up ↑
5383 5571  
5384 5572  static void
5385 5573  output_auth(FILE *fp, struct zone_admintab *admintab)
5386 5574  {
5387 5575          (void) fprintf(fp, "%s:\n", rt_to_str(RT_ADMIN));
5388 5576          output_prop(fp, PT_USER, admintab->zone_admin_user, B_TRUE);
5389 5577          output_prop(fp, PT_AUTHS, admintab->zone_admin_auths, B_TRUE);
5390 5578  }
5391 5579  
5392 5580  static void
     5581 +output_secflags(FILE *fp, struct zone_secflagstab *sftab)
     5582 +{
     5583 +        (void) fprintf(fp, "%s:\n", rt_to_str(RT_SECFLAGS));
     5584 +        output_prop(fp, PT_DEFAULT, sftab->zone_secflags_default, B_TRUE);
     5585 +        output_prop(fp, PT_LOWER, sftab->zone_secflags_lower, B_TRUE);
     5586 +        output_prop(fp, PT_UPPER, sftab->zone_secflags_upper, B_TRUE);
     5587 +}
     5588 +
     5589 +static void
5393 5590  info_auth(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5394 5591  {
5395 5592          struct zone_admintab lookup, user;
5396 5593          boolean_t output = B_FALSE;
5397 5594          int err;
5398 5595  
5399 5596          if ((err = zonecfg_setadminent(handle)) != Z_OK) {
5400 5597                  zone_perror(zone, err, B_TRUE);
5401 5598                  return;
5402 5599          }
↓ open down ↓ 13 lines elided ↑ open up ↑
5416 5613          (void) zonecfg_endadminent(handle);
5417 5614          /*
5418 5615           * If a property n/v pair was specified, warn the user if there was
5419 5616           * nothing to output.
5420 5617           */
5421 5618          if (!output && cmd->cmd_prop_nv_pairs > 0)
5422 5619                  (void) printf(gettext("No such %s resource.\n"),
5423 5620                      rt_to_str(RT_ADMIN));
5424 5621  }
5425 5622  
     5623 +static void
     5624 +info_secflags(zone_dochandle_t handle, FILE *fp)
     5625 +{
     5626 +        struct zone_secflagstab sftab;
     5627 +        int err;
     5628 +
     5629 +        if ((err = zonecfg_lookup_secflags(handle, &sftab)) != Z_OK) {
     5630 +                zone_perror(zone, err, B_TRUE);
     5631 +                return;
     5632 +        }
     5633 +
     5634 +        output_secflags(fp, &sftab);
     5635 +}
     5636 +
5426 5637  void
5427 5638  info_func(cmd_t *cmd)
5428 5639  {
5429 5640          FILE *fp = stdout;
5430 5641          boolean_t need_to_close = B_FALSE;
5431 5642          int type;
5432 5643          int res1, res2;
5433 5644          uint64_t swap_limit;
5434 5645          uint64_t locked_limit;
5435 5646  
↓ open down ↓ 42 lines elided ↑ open up ↑
5478 5689                          res1 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP,
5479 5690                              &swap_limit);
5480 5691                          res2 = zonecfg_get_aliased_rctl(handle,
5481 5692                              ALIAS_MAXLOCKEDMEM, &locked_limit);
5482 5693                          output_mcap(fp, &in_progress_mcaptab, res1, swap_limit,
5483 5694                              res2, locked_limit);
5484 5695                          break;
5485 5696                  case RT_ADMIN:
5486 5697                          output_auth(fp, &in_progress_admintab);
5487 5698                          break;
     5699 +                case RT_SECFLAGS:
     5700 +                        output_secflags(fp, &in_progress_secflagstab);
     5701 +                        break;
5488 5702                  }
5489 5703                  goto cleanup;
5490 5704          }
5491 5705  
5492 5706          type = cmd->cmd_res_type;
5493 5707  
5494 5708          if (gz_invalid_rt_property(type)) {
5495 5709                  zerr(gettext("%s is not a valid property for the global zone."),
5496 5710                      rt_to_str(type));
5497 5711                  goto cleanup;
↓ open down ↓ 36 lines elided ↑ open up ↑
5534 5748                  }
5535 5749                  info_pset(handle, fp);
5536 5750                  info_pcap(fp);
5537 5751                  info_mcap(handle, fp);
5538 5752                  if (!global_zone) {
5539 5753                          info_attr(handle, fp, cmd);
5540 5754                          info_ds(handle, fp, cmd);
5541 5755                          info_auth(handle, fp, cmd);
5542 5756                  }
5543 5757                  info_rctl(handle, fp, cmd);
     5758 +                info_secflags(handle, fp);
5544 5759                  break;
5545 5760          case RT_ZONENAME:
5546 5761                  info_zonename(handle, fp);
5547 5762                  break;
5548 5763          case RT_ZONEPATH:
5549 5764                  info_zonepath(handle, fp);
5550 5765                  break;
5551 5766          case RT_BRAND:
5552 5767                  info_brand(handle, fp);
5553 5768                  break;
↓ open down ↓ 65 lines elided ↑ open up ↑
5619 5834                  break;
5620 5835          case RT_HOSTID:
5621 5836                  info_hostid(handle, fp);
5622 5837                  break;
5623 5838          case RT_ADMIN:
5624 5839                  info_auth(handle, fp, cmd);
5625 5840                  break;
5626 5841          case RT_FS_ALLOWED:
5627 5842                  info_fs_allowed(handle, fp);
5628 5843                  break;
     5844 +        case RT_SECFLAGS:
     5845 +                info_secflags(handle, fp);
     5846 +                break;
5629 5847          default:
5630 5848                  zone_perror(rt_to_str(cmd->cmd_res_type), Z_NO_RESOURCE_TYPE,
5631 5849                      B_TRUE);
5632 5850          }
5633 5851  
5634 5852  cleanup:
5635 5853          if (need_to_close)
5636 5854                  (void) pager_close(fp);
5637 5855  }
5638 5856  
↓ open down ↓ 131 lines elided ↑ open up ↑
5770 5988          }
5771 5989          strlcpy(tmp->xif_name, nwif->zone_nwif_physical,
5772 5990              sizeof (tmp->xif_name));
5773 5991          tmp->xif_has_defrouter = (strlen(nwif->zone_nwif_defrouter) > 0);
5774 5992          tmp->xif_has_address = (strlen(nwif->zone_nwif_allowed_address) > 0);
5775 5993          tmp->xif_next = xif;
5776 5994          xif = tmp;
5777 5995          return (B_TRUE);
5778 5996  }
5779 5997  
     5998 +boolean_t
     5999 +verify_secflags(struct zone_secflagstab *tab)
     6000 +{
     6001 +        secflagdelta_t def = {0};
     6002 +        secflagdelta_t upper = {0};
     6003 +        secflagdelta_t lower = {0};
     6004 +        boolean_t def_set = B_FALSE;
     6005 +        boolean_t upper_set = B_FALSE;
     6006 +        boolean_t lower_set = B_FALSE;
     6007 +        boolean_t ret = B_TRUE;
     6008 +
     6009 +        if (strlen(tab->zone_secflags_default) > 0) {
     6010 +                def_set = B_TRUE;
     6011 +                if (secflags_parse(NULL, tab->zone_secflags_default,
     6012 +                    &def) == -1) {
     6013 +                        zerr(gettext("default security flags '%s' are invalid"),
     6014 +                            tab->zone_secflags_default);
     6015 +                        ret = B_FALSE;
     6016 +                }
     6017 +        } else {
     6018 +                secflags_zero(&def.psd_assign);
     6019 +                def.psd_ass_active = B_TRUE;
     6020 +        }
     6021 +
     6022 +        if (strlen(tab->zone_secflags_upper) > 0) {
     6023 +                upper_set = B_TRUE;
     6024 +                if (secflags_parse(NULL, tab->zone_secflags_upper,
     6025 +                    &upper) == -1) {
     6026 +                        zerr(gettext("upper security flags '%s' are invalid"),
     6027 +                            tab->zone_secflags_upper);
     6028 +                        ret = B_FALSE;
     6029 +                }
     6030 +        } else {
     6031 +                secflags_fullset(&upper.psd_assign);
     6032 +                upper.psd_ass_active = B_TRUE;
     6033 +        }
     6034 +
     6035 +        if (strlen(tab->zone_secflags_lower) > 0) {
     6036 +                lower_set = B_TRUE;
     6037 +                if (secflags_parse(NULL, tab->zone_secflags_lower,
     6038 +                    &lower) == -1) {
     6039 +                        zerr(gettext("lower security flags '%s' are invalid"),
     6040 +                            tab->zone_secflags_lower);
     6041 +                        ret = B_FALSE;
     6042 +                }
     6043 +        } else {
     6044 +                secflags_zero(&lower.psd_assign);
     6045 +                lower.psd_ass_active = B_TRUE;
     6046 +        }
     6047 +
     6048 +        if (def_set && !def.psd_ass_active) {
     6049 +                zerr(gettext("only assignment of security flags is "
     6050 +                    "allowed (default: %s)"), tab->zone_secflags_default);
     6051 +        }
     6052 +
     6053 +        if (lower_set && !lower.psd_ass_active) {
     6054 +                zerr(gettext("only assignment of security flags is "
     6055 +                    "allowed (lower: %s)"), tab->zone_secflags_lower);
     6056 +        }
     6057 +
     6058 +        if (upper_set && !upper.psd_ass_active) {
     6059 +                zerr(gettext("only assignment of security flags is "
     6060 +                    "allowed (upper: %s)"), tab->zone_secflags_upper);
     6061 +        }
     6062 +
     6063 +        if (def.psd_assign & ~upper.psd_assign) { /* In default but not upper */
     6064 +                zerr(gettext("default secflags must be within the "
     6065 +                    "upper limit"));
     6066 +                ret = B_FALSE;
     6067 +        }
     6068 +        if (lower.psd_assign & ~def.psd_assign) { /* In lower but not default */
     6069 +                zerr(gettext("default secflags must be above the lower limit"));
     6070 +                ret = B_FALSE;
     6071 +        }
     6072 +        if (lower.psd_assign & ~upper.psd_assign) { /* In lower but not upper */
     6073 +                zerr(gettext("lower secflags must be within the upper limit"));
     6074 +                ret = B_FALSE;
     6075 +        }
     6076 +
     6077 +        return (ret);
     6078 +}
     6079 +
5780 6080  /*
5781 6081   * See the DTD for which attributes are required for which resources.
5782 6082   *
5783 6083   * This function can be called by commit_func(), which needs to save things,
5784 6084   * in addition to the general call from parse_and_run(), which doesn't need
5785 6085   * things saved.  Since the parameters are standardized, we distinguish by
5786 6086   * having commit_func() call here with cmd->cmd_arg set to "save" to indicate
5787 6087   * that a save is needed.
5788 6088   */
5789 6089  void
5790 6090  verify_func(cmd_t *cmd)
5791 6091  {
5792 6092          struct zone_nwiftab nwiftab;
5793 6093          struct zone_fstab fstab;
5794 6094          struct zone_attrtab attrtab;
5795 6095          struct zone_rctltab rctltab;
5796 6096          struct zone_dstab dstab;
5797 6097          struct zone_psettab psettab;
5798 6098          struct zone_admintab admintab;
     6099 +        struct zone_secflagstab secflagstab;
5799 6100          char zonepath[MAXPATHLEN];
5800 6101          char sched[MAXNAMELEN];
5801 6102          char brand[MAXNAMELEN];
5802 6103          char hostidp[HW_HOSTID_LEN];
5803 6104          char fsallowedp[ZONE_FS_ALLOWED_MAX];
5804 6105          priv_set_t *privs;
5805 6106          char *privname = NULL;
5806 6107          int err, ret_val = Z_OK, arg;
5807 6108          int pset_res;
5808 6109          boolean_t save = B_FALSE;
↓ open down ↓ 276 lines elided ↑ open up ↑
6085 6386                              admintab.zone_admin_user);
6086 6387                          ret_val = Z_BAD_PROPERTY;
6087 6388                  }
6088 6389                  if ((ret_val == Z_OK) && (!zonecfg_valid_auths(
6089 6390                      admintab.zone_admin_auths, zone))) {
6090 6391                          ret_val = Z_BAD_PROPERTY;
6091 6392                  }
6092 6393          }
6093 6394          (void) zonecfg_endadminent(handle);
6094 6395  
     6396 +        if ((err = zonecfg_getsecflagsent(handle, &secflagstab)) != Z_OK) {
     6397 +                zone_perror(zone, err, B_TRUE);
     6398 +                return;
     6399 +        }
     6400 +
     6401 +        /*
     6402 +         * No properties are required, but any specified should be
     6403 +         * valid
     6404 +         */
     6405 +        if (verify_secflags(&secflagstab) != B_TRUE) {
     6406 +                /* Error is reported from verify_secflags */
     6407 +                ret_val = Z_BAD_PROPERTY;
     6408 +        }
     6409 +
6095 6410          if (!global_scope) {
6096 6411                  zerr(gettext("resource specification incomplete"));
6097 6412                  saw_error = B_TRUE;
6098 6413                  if (ret_val == Z_OK)
6099 6414                          ret_val = Z_INSUFFICIENT_SPEC;
6100 6415          }
6101 6416  
6102 6417          if (save) {
6103 6418                  if (ret_val == Z_OK) {
6104 6419                          if ((ret_val = zonecfg_save(handle)) == Z_OK) {
↓ open down ↓ 569 lines elided ↑ open up ↑
6674 6989                                  return;
6675 6990                          }
6676 6991                          err = zonecfg_add_admin(handle,
6677 6992                              &in_progress_admintab, zone);
6678 6993                  } else {
6679 6994                          err = zonecfg_modify_admin(handle,
6680 6995                              &old_admintab, &in_progress_admintab,
6681 6996                              zone);
6682 6997                  }
6683 6998                  break;
     6999 +        case RT_SECFLAGS:
     7000 +                if (verify_secflags(&in_progress_secflagstab) != B_TRUE) {
     7001 +                        saw_error = B_TRUE;
     7002 +                        return;
     7003 +                }
     7004 +
     7005 +                if (end_op == CMD_ADD) {
     7006 +                        err = zonecfg_add_secflags(handle,
     7007 +                            &in_progress_secflagstab);
     7008 +                } else {
     7009 +                        err = zonecfg_modify_secflags(handle,
     7010 +                            &old_secflagstab, &in_progress_secflagstab);
     7011 +                }
     7012 +                break;
6684 7013          default:
6685 7014                  zone_perror(rt_to_str(resource_scope), Z_NO_RESOURCE_TYPE,
6686 7015                      B_TRUE);
6687 7016                  saw_error = B_TRUE;
6688 7017                  return;
6689 7018          }
6690 7019  
6691 7020          if (err != Z_OK) {
6692 7021                  zone_perror(zone, err, B_TRUE);
6693 7022          } else {
↓ open down ↓ 607 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX