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.


  60  * described above is constructed on the fly.  The zone is then created using
  61  * $ZONEPATH/lu as the root.
  62  *
  63  * Note that scratch zones are inactive.  The zone's bits are not running and
  64  * likely cannot be run correctly until upgrade is done.  Init is not running
  65  * there, nor is SMF.  Because of this, the "mounted" state of a scratch zone
  66  * is not a part of the usual halt/ready/boot state machine.
  67  */
  68 
  69 #include <sys/param.h>
  70 #include <sys/mount.h>
  71 #include <sys/mntent.h>
  72 #include <sys/socket.h>
  73 #include <sys/utsname.h>
  74 #include <sys/types.h>
  75 #include <sys/stat.h>
  76 #include <sys/sockio.h>
  77 #include <sys/stropts.h>
  78 #include <sys/conf.h>
  79 #include <sys/systeminfo.h>

  80 
  81 #include <libdlpi.h>
  82 #include <libdllink.h>
  83 #include <libdlvlan.h>
  84 
  85 #include <inet/tcp.h>
  86 #include <arpa/inet.h>
  87 #include <netinet/in.h>
  88 #include <net/route.h>
  89 
  90 #include <stdio.h>
  91 #include <errno.h>
  92 #include <fcntl.h>
  93 #include <unistd.h>
  94 #include <rctl.h>
  95 #include <stdlib.h>
  96 #include <string.h>
  97 #include <strings.h>
  98 #include <wait.h>
  99 #include <limits.h>


4574 
4575         if (res == Z_BAD_PROPERTY) {
4576                 return (Z_OK);
4577         } else if (res != Z_OK) {
4578                 report_prop_err(zlogp, "hostid", hostidp, res);
4579                 return (res);
4580         }
4581 
4582         hostid = (unsigned int)strtoul(hostidp, NULL, 16);
4583         if ((res = zone_setattr(zoneid, ZONE_ATTR_HOSTID, &hostid,
4584             sizeof (hostid))) != 0) {
4585                 zerror(zlogp, B_TRUE,
4586                     "zone hostid is not valid: %s: %d", hostidp, res);
4587                 return (Z_SYSTEM);
4588         }
4589 
4590         return (res);
4591 }
4592 
4593 static int


























































































4594 setup_zone_fs_allowed(zone_dochandle_t handle, zlog_t *zlogp, zoneid_t zoneid)
4595 {
4596         char fsallowed[ZONE_FS_ALLOWED_MAX];
4597         char *fsallowedp = fsallowed;
4598         int len = sizeof (fsallowed);
4599         int res;
4600 
4601         res = zonecfg_get_fs_allowed(handle, fsallowed, len);
4602 
4603         if (res == Z_BAD_PROPERTY) {
4604                 /* No value, set the defaults */
4605                 (void) strlcpy(fsallowed, DFLT_FS_ALLOWED, len);
4606         } else if (res != Z_OK) {
4607                 report_prop_err(zlogp, "fs-allowed", fsallowed, res);
4608                 return (res);
4609         } else if (fsallowed[0] == '-') {
4610                 /* dropping default privs - use remaining list */
4611                 if (fsallowed[1] != ',')
4612                         return (Z_OK);
4613                 fsallowedp += 2;
4614                 len -= 2;
4615         } else {
4616                 /* Has a value, append the defaults */
4617                 if (strlcat(fsallowed, ",", len) >= len ||
4618                     strlcat(fsallowed, DFLT_FS_ALLOWED, len) >= len) {
4619                         report_prop_err(zlogp, "fs-allowed", fsallowed,
4620                             Z_TOO_BIG);
4621                         return (Z_TOO_BIG);
4622                 }
4623         }
4624 
4625         if (zone_setattr(zoneid, ZONE_ATTR_FS_ALLOWED, fsallowedp, len) != 0) {
4626                 zerror(zlogp, B_TRUE,
4627                     "fs-allowed couldn't be set: %s: %d", fsallowedp, res);
4628                 return (Z_SYSTEM);
4629         }
4630 


4635 setup_zone_attrs(zlog_t *zlogp, char *zone_namep, zoneid_t zoneid)
4636 {
4637         zone_dochandle_t handle;
4638         int res = Z_OK;
4639 
4640         if ((handle = zonecfg_init_handle()) == NULL) {
4641                 zerror(zlogp, B_TRUE, "getting zone configuration handle");
4642                 return (Z_BAD_HANDLE);
4643         }
4644         if ((res = zonecfg_get_snapshot_handle(zone_namep, handle)) != Z_OK) {
4645                 zerror(zlogp, B_FALSE, "invalid configuration");
4646                 goto out;
4647         }
4648 
4649         if ((res = setup_zone_hostid(handle, zlogp, zoneid)) != Z_OK)
4650                 goto out;
4651 
4652         if ((res = setup_zone_fs_allowed(handle, zlogp, zoneid)) != Z_OK)
4653                 goto out;
4654 



4655 out:
4656         zonecfg_fini_handle(handle);
4657         return (res);
4658 }
4659 
4660 zoneid_t
4661 vplat_create(zlog_t *zlogp, zone_mnt_t mount_cmd)
4662 {
4663         zoneid_t rval = -1;
4664         priv_set_t *privs;
4665         char rootpath[MAXPATHLEN];
4666         char *rctlbuf = NULL;
4667         size_t rctlbufsz = 0;
4668         char *zfsbuf = NULL;
4669         size_t zfsbufsz = 0;
4670         zoneid_t zoneid = -1;
4671         int xerr;
4672         char *kzone;
4673         FILE *fp = NULL;
4674         tsol_zcent_t *zcent = NULL;




  60  * described above is constructed on the fly.  The zone is then created using
  61  * $ZONEPATH/lu as the root.
  62  *
  63  * Note that scratch zones are inactive.  The zone's bits are not running and
  64  * likely cannot be run correctly until upgrade is done.  Init is not running
  65  * there, nor is SMF.  Because of this, the "mounted" state of a scratch zone
  66  * is not a part of the usual halt/ready/boot state machine.
  67  */
  68 
  69 #include <sys/param.h>
  70 #include <sys/mount.h>
  71 #include <sys/mntent.h>
  72 #include <sys/socket.h>
  73 #include <sys/utsname.h>
  74 #include <sys/types.h>
  75 #include <sys/stat.h>
  76 #include <sys/sockio.h>
  77 #include <sys/stropts.h>
  78 #include <sys/conf.h>
  79 #include <sys/systeminfo.h>
  80 #include <sys/secflags.h>
  81 
  82 #include <libdlpi.h>
  83 #include <libdllink.h>
  84 #include <libdlvlan.h>
  85 
  86 #include <inet/tcp.h>
  87 #include <arpa/inet.h>
  88 #include <netinet/in.h>
  89 #include <net/route.h>
  90 
  91 #include <stdio.h>
  92 #include <errno.h>
  93 #include <fcntl.h>
  94 #include <unistd.h>
  95 #include <rctl.h>
  96 #include <stdlib.h>
  97 #include <string.h>
  98 #include <strings.h>
  99 #include <wait.h>
 100 #include <limits.h>


4575 
4576         if (res == Z_BAD_PROPERTY) {
4577                 return (Z_OK);
4578         } else if (res != Z_OK) {
4579                 report_prop_err(zlogp, "hostid", hostidp, res);
4580                 return (res);
4581         }
4582 
4583         hostid = (unsigned int)strtoul(hostidp, NULL, 16);
4584         if ((res = zone_setattr(zoneid, ZONE_ATTR_HOSTID, &hostid,
4585             sizeof (hostid))) != 0) {
4586                 zerror(zlogp, B_TRUE,
4587                     "zone hostid is not valid: %s: %d", hostidp, res);
4588                 return (Z_SYSTEM);
4589         }
4590 
4591         return (res);
4592 }
4593 
4594 static int
4595 setup_zone_secflags(zone_dochandle_t handle, zlog_t *zlogp, zoneid_t zoneid)
4596 {
4597         psecflags_t secflags;
4598         struct zone_secflagstab tab = {0};
4599         secflagdelta_t delt;
4600         int res;
4601 
4602         res = zonecfg_lookup_secflags(handle, &tab);
4603 
4604         if ((res != Z_OK) &&
4605             /* The general defaulting code will handle this */
4606             (res != Z_NO_ENTRY) && (res != Z_BAD_PROPERTY)) {
4607                 zerror(zlogp, B_FALSE, "security-flags property is "
4608                     "invalid: %d", res);
4609                 return (res);
4610         }
4611 
4612         if (strlen(tab.zone_secflags_lower) == 0)
4613                 (void) strlcpy(tab.zone_secflags_lower, "none",
4614                     sizeof (tab.zone_secflags_lower));
4615         if (strlen(tab.zone_secflags_default) == 0)
4616                 (void) strlcpy(tab.zone_secflags_default,
4617                     tab.zone_secflags_lower,
4618                     sizeof (tab.zone_secflags_default));
4619         if (strlen(tab.zone_secflags_upper) == 0)
4620                 (void) strlcpy(tab.zone_secflags_upper, "all",
4621                     sizeof (tab.zone_secflags_upper));
4622 
4623         if (secflags_parse(NULL, tab.zone_secflags_default,
4624             &delt) == -1) {
4625                 zerror(zlogp, B_FALSE, "default security-flags: '%s'"
4626                     "are invalid", tab.zone_secflags_default);
4627                 return (Z_BAD_PROPERTY);
4628         } else if (delt.psd_ass_active != B_TRUE) {
4629                 zerror(zlogp, B_FALSE, "relative security-flags are not "
4630                     "allowed in zone configuration (default "
4631                     "security-flags: '%s')",
4632                     tab.zone_secflags_default);
4633                 return (Z_BAD_PROPERTY);
4634         } else {
4635                 secflags_copy(&secflags.psf_inherit, &delt.psd_assign);
4636                 secflags_copy(&secflags.psf_effective, &delt.psd_assign);
4637         }
4638 
4639         if (secflags_parse(NULL, tab.zone_secflags_lower,
4640             &delt) == -1) {
4641                 zerror(zlogp, B_FALSE, "lower security-flags: '%s'"
4642                     "are invalid", tab.zone_secflags_lower);
4643                 return (Z_BAD_PROPERTY);
4644         } else if (delt.psd_ass_active != B_TRUE) {
4645                 zerror(zlogp, B_FALSE, "relative security-flags are not "
4646                     "allowed in zone configuration (lower "
4647                     "security-flags: '%s')",
4648                     tab.zone_secflags_lower);
4649                 return (Z_BAD_PROPERTY);
4650         } else {
4651                 secflags_copy(&secflags.psf_lower, &delt.psd_assign);
4652         }
4653 
4654         if (secflags_parse(NULL, tab.zone_secflags_upper,
4655             &delt) == -1) {
4656                 zerror(zlogp, B_FALSE, "upper security-flags: '%s'"
4657                     "are invalid", tab.zone_secflags_upper);
4658                 return (Z_BAD_PROPERTY);
4659         } else if (delt.psd_ass_active != B_TRUE) {
4660                 zerror(zlogp, B_FALSE, "relative security-flags are not "
4661                     "allowed in zone configuration (upper "
4662                     "security-flags: '%s')",
4663                     tab.zone_secflags_upper);
4664                 return (Z_BAD_PROPERTY);
4665         } else {
4666                 secflags_copy(&secflags.psf_upper, &delt.psd_assign);
4667         }
4668 
4669         if (!psecflags_validate(&secflags)) {
4670                 zerror(zlogp, B_TRUE, "security-flags violate invariants");
4671                 return (Z_BAD_PROPERTY);
4672         }
4673 
4674         if ((res = zone_setattr(zoneid, ZONE_ATTR_SECFLAGS, &secflags,
4675             sizeof (secflags))) != 0) {
4676                 zerror(zlogp, B_TRUE,
4677                     "security-flags couldn't be set: %d", res);
4678                 return (Z_SYSTEM);
4679         }
4680 
4681         return (Z_OK);
4682 }
4683 
4684 static int
4685 setup_zone_fs_allowed(zone_dochandle_t handle, zlog_t *zlogp, zoneid_t zoneid)
4686 {
4687         char fsallowed[ZONE_FS_ALLOWED_MAX];
4688         char *fsallowedp = fsallowed;
4689         int len = sizeof (fsallowed);
4690         int res;
4691 
4692         res = zonecfg_get_fs_allowed(handle, fsallowed, len);
4693 
4694         if (res == Z_BAD_PROPERTY) {
4695                 /* No value, set the defaults */
4696                 (void) strlcpy(fsallowed, DFLT_FS_ALLOWED, len);
4697         } else if (res != Z_OK) {
4698                 report_prop_err(zlogp, "fs-allowed", fsallowed, res);
4699                 return (res);
4700         } else if (fsallowed[0] == '-') {
4701                 /* dropping default filesystems - use remaining list */
4702                 if (fsallowed[1] != ',')
4703                         return (Z_OK);
4704                 fsallowedp += 2;
4705                 len -= 2;
4706         } else {
4707                 /* Has a value, append the defaults */
4708                 if (strlcat(fsallowed, ",", len) >= len ||
4709                     strlcat(fsallowed, DFLT_FS_ALLOWED, len) >= len) {
4710                         report_prop_err(zlogp, "fs-allowed", fsallowed,
4711                             Z_TOO_BIG);
4712                         return (Z_TOO_BIG);
4713                 }
4714         }
4715 
4716         if (zone_setattr(zoneid, ZONE_ATTR_FS_ALLOWED, fsallowedp, len) != 0) {
4717                 zerror(zlogp, B_TRUE,
4718                     "fs-allowed couldn't be set: %s: %d", fsallowedp, res);
4719                 return (Z_SYSTEM);
4720         }
4721 


4726 setup_zone_attrs(zlog_t *zlogp, char *zone_namep, zoneid_t zoneid)
4727 {
4728         zone_dochandle_t handle;
4729         int res = Z_OK;
4730 
4731         if ((handle = zonecfg_init_handle()) == NULL) {
4732                 zerror(zlogp, B_TRUE, "getting zone configuration handle");
4733                 return (Z_BAD_HANDLE);
4734         }
4735         if ((res = zonecfg_get_snapshot_handle(zone_namep, handle)) != Z_OK) {
4736                 zerror(zlogp, B_FALSE, "invalid configuration");
4737                 goto out;
4738         }
4739 
4740         if ((res = setup_zone_hostid(handle, zlogp, zoneid)) != Z_OK)
4741                 goto out;
4742 
4743         if ((res = setup_zone_fs_allowed(handle, zlogp, zoneid)) != Z_OK)
4744                 goto out;
4745 
4746         if ((res = setup_zone_secflags(handle, zlogp, zoneid)) != Z_OK)
4747                 goto out;
4748 
4749 out:
4750         zonecfg_fini_handle(handle);
4751         return (res);
4752 }
4753 
4754 zoneid_t
4755 vplat_create(zlog_t *zlogp, zone_mnt_t mount_cmd)
4756 {
4757         zoneid_t rval = -1;
4758         priv_set_t *privs;
4759         char rootpath[MAXPATHLEN];
4760         char *rctlbuf = NULL;
4761         size_t rctlbufsz = 0;
4762         char *zfsbuf = NULL;
4763         size_t zfsbufsz = 0;
4764         zoneid_t zoneid = -1;
4765         int xerr;
4766         char *kzone;
4767         FILE *fp = NULL;
4768         tsol_zcent_t *zcent = NULL;