diff options
author | johnlev <none@none> | 2008-06-03 08:27:11 -0700 |
---|---|---|
committer | johnlev <none@none> | 2008-06-03 08:27:11 -0700 |
commit | b26a64ae582e72d0b4c710cd8eba9c4afd4a9fdd (patch) | |
tree | bd07953ac9f0bacf8ba5de284c3e1a03845cc4d3 | |
parent | 7bc3486009c1b9444dc46d6894eabd5845083a14 (diff) | |
download | illumos-gate-b26a64ae582e72d0b4c710cd8eba9c4afd4a9fdd.tar.gz |
PSARC 2008/289 Least Privilege for xVM
6674678 PSARC 2008/289 Least Privilege for xVM
-rw-r--r-- | usr/src/cmd/Adm/group | 1 | ||||
-rw-r--r-- | usr/src/cmd/Adm/sun/passwd | 1 | ||||
-rw-r--r-- | usr/src/cmd/Adm/sun/shadow | 1 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/zone/config.xml | 2 | ||||
-rw-r--r-- | usr/src/lib/brand/native/zone/config.xml | 2 | ||||
-rw-r--r-- | usr/src/lib/brand/sn1/zone/config.xml | 2 | ||||
-rw-r--r-- | usr/src/pkgdefs/common_files/i.group | 18 | ||||
-rw-r--r-- | usr/src/pkgdefs/common_files/i.minorperm_i386 | 5 | ||||
-rw-r--r-- | usr/src/pkgdefs/common_files/i.passwd | 25 | ||||
-rw-r--r-- | usr/src/pkgdefs/common_files/i.shadow | 11 | ||||
-rw-r--r-- | usr/src/tools/scripts/bfu.sh | 5 | ||||
-rw-r--r-- | usr/src/uts/common/os/policy.c | 18 | ||||
-rw-r--r-- | usr/src/uts/common/os/priv_defs | 12 | ||||
-rw-r--r-- | usr/src/uts/common/sys/policy.h | 1 | ||||
-rw-r--r-- | usr/src/uts/common/xen/io/evtchn_dev.c | 18 | ||||
-rw-r--r-- | usr/src/uts/common/xen/io/xenbus_dev.c | 39 | ||||
-rw-r--r-- | usr/src/uts/i86xpv/io/privcmd.c | 10 | ||||
-rw-r--r-- | usr/src/uts/intel/os/minor_perm | 5 |
18 files changed, 159 insertions, 17 deletions
diff --git a/usr/src/cmd/Adm/group b/usr/src/cmd/Adm/group index 2e056fbf81..d59f46c7cc 100644 --- a/usr/src/cmd/Adm/group +++ b/usr/src/cmd/Adm/group @@ -14,6 +14,7 @@ sysadmin::14: games::20: smmsp::25: gdm::50: +xvm::60: mysql::70: webservd::80: postgres::90: diff --git a/usr/src/cmd/Adm/sun/passwd b/usr/src/cmd/Adm/sun/passwd index ded8c1c9cc..9790c338c3 100644 --- a/usr/src/cmd/Adm/sun/passwd +++ b/usr/src/cmd/Adm/sun/passwd @@ -10,6 +10,7 @@ dladm:x:15:3:Datalink Admin:/: smmsp:x:25:25:SendMail Message Submission Program:/: listen:x:37:4:Network Admin:/usr/net/nls: gdm:x:50:50:GDM Reserved UID:/: +xvm:x:60:60:xVM User:/: mysql:x:70:70:MySQL Reserved UID:/: webservd:x:80:80:WebServer Reserved UID:/: postgres:x:90:90:PostgreSQL Reserved UID:/:/usr/bin/pfksh diff --git a/usr/src/cmd/Adm/sun/shadow b/usr/src/cmd/Adm/sun/shadow index 4e40d12635..50f0f9f8b9 100644 --- a/usr/src/cmd/Adm/sun/shadow +++ b/usr/src/cmd/Adm/sun/shadow @@ -10,6 +10,7 @@ dladm:*LK*::::::: smmsp:NP:6445:::::: listen:*LK*::::::: gdm:*LK*::::::: +xvm:*LK*:6445:::::: mysql:NP::::::: webservd:*LK*::::::: postgres:NP::::::: diff --git a/usr/src/lib/brand/lx/zone/config.xml b/usr/src/lib/brand/lx/zone/config.xml index 1e2fd2f01d..0f252c502d 100644 --- a/usr/src/lib/brand/lx/zone/config.xml +++ b/usr/src/lib/brand/lx/zone/config.xml @@ -87,6 +87,8 @@ <privilege set="prohibited" name="sys_net_config" /> <privilege set="prohibited" name="sys_res_config" /> <privilege set="prohibited" name="sys_suser_compat" /> + <privilege set="prohibited" name="xvm_control" /> + <privilege set="prohibited" name="virt_manage" /> <privilege set="required" name="proc_exec" /> <privilege set="required" name="proc_fork" /> diff --git a/usr/src/lib/brand/native/zone/config.xml b/usr/src/lib/brand/native/zone/config.xml index cfa0f87ac8..42318a647b 100644 --- a/usr/src/lib/brand/native/zone/config.xml +++ b/usr/src/lib/brand/native/zone/config.xml @@ -89,6 +89,8 @@ <privilege set="prohibited" name="sys_net_config" /> <privilege set="prohibited" name="sys_res_config" /> <privilege set="prohibited" name="sys_suser_compat" /> + <privilege set="prohibited" name="xvm_control" /> + <privilege set="prohibited" name="virt_manage" /> <privilege set="required" name="proc_exec" /> <privilege set="required" name="proc_fork" /> diff --git a/usr/src/lib/brand/sn1/zone/config.xml b/usr/src/lib/brand/sn1/zone/config.xml index 6afccf3475..de3cf2a7b2 100644 --- a/usr/src/lib/brand/sn1/zone/config.xml +++ b/usr/src/lib/brand/sn1/zone/config.xml @@ -89,6 +89,8 @@ <privilege set="prohibited" name="sys_net_config" /> <privilege set="prohibited" name="sys_res_config" /> <privilege set="prohibited" name="sys_suser_compat" /> + <privilege set="prohibited" name="xvm_control" /> + <privilege set="prohibited" name="virt_manage" /> <privilege set="required" name="proc_exec" /> <privilege set="required" name="proc_fork" /> diff --git a/usr/src/pkgdefs/common_files/i.group b/usr/src/pkgdefs/common_files/i.group index 04e943e57c..a1da98e187 100644 --- a/usr/src/pkgdefs/common_files/i.group +++ b/usr/src/pkgdefs/common_files/i.group @@ -215,6 +215,24 @@ do printf '/^smmsp::25:\ni\n%s\n.\nw\nq\n' \ "$GAMESGROUP_LINE" | ed -s $dest > /dev/null fi + # + # Add the 'xvm' group if it doesn't already exist. + # + XVMGROUP_LINE="xvm::60:" + cur_name=`awk -F: '$3 == 60 {print $1}' $dest` + cur_id=`awk -F: '$1 == "xvm" {print $3}' $dest` + if [ ! -z "$cur_name" -a "$cur_name" != "xvm" ]; then + echo "ERROR: Reserved GID 60 already assigned" \ + "to '$cur_name'" >> /tmp/CLEANUP + elif [ ! -z "$cur_id" -a "$cur_id" != "60" ]; then + echo "NOTE: xvm group already assigned" \ + "to id '$cur_id'" >> /tmp/CLEANUP + elif grep "$XVMGROUP_LINE" $dest 2>&1 >/dev/null; then + : + else + printf '/^mysql::70:\ni\n%s\n.\nw\nq\n' \ + "$XVMGROUP_LINE" | ed -s $dest > /dev/null + fi fi done exit 0 diff --git a/usr/src/pkgdefs/common_files/i.minorperm_i386 b/usr/src/pkgdefs/common_files/i.minorperm_i386 index e5acb8e7f1..e7b002bf05 100644 --- a/usr/src/pkgdefs/common_files/i.minorperm_i386 +++ b/usr/src/pkgdefs/common_files/i.minorperm_i386 @@ -331,6 +331,11 @@ acpi_drv:* smbsrv:* vscan:* nsmb:* +balloon:* +domcaps:* +evtchn:* +privcmd:* +xenbus:* EOF } diff --git a/usr/src/pkgdefs/common_files/i.passwd b/usr/src/pkgdefs/common_files/i.passwd index b9c627df7d..c28080ce62 100644 --- a/usr/src/pkgdefs/common_files/i.passwd +++ b/usr/src/pkgdefs/common_files/i.passwd @@ -129,8 +129,7 @@ do "$POSTGRES_LIN" | ed -s $dest > /dev/null fi - - + # # Add the 'mysql' user if it doesn't exist. # MYSQL_LIN="mysql:x:70:70:MySQL Reserved UID:/:" @@ -149,8 +148,6 @@ do "$MYSQL_LIN" | ed -s $dest > /dev/null fi - - # # Add the 'svctag' user if it doesn't exist. # @@ -184,6 +181,26 @@ do printf '/^nuucp:x\na\n%s\n.\nw\nq\n' \ "$DLADM_LIN" | ed -s $dest > /dev/null fi + + # + # Add the 'xvm' user if it doesn't exist. + # + XVM_LIN="xvm:x:60:60:xVM User:/:" + cur_name=`awk -F: '$3 == 60 { print $1 }' $dest` + cur_id=`awk -F: '$1 == "xvm" { print $3 }' $dest` + if [ ! -z "$cur_name" -a "$cur_name" != "xvm" ]; then + echo "ERROR: Reserved UID 60 already assigned" \ + "to '$cur_name'" >> /tmp/CLEANUP + elif [ ! -z "$cur_id" -a "$cur_id" != "60" ]; then + echo "NOTE: xvm username already assigned" \ + "to id '$cur_id'" >> /tmp/CLEANUP + elif grep "$XVM_LIN" $dest 2>&1 >/dev/null; then + : + else + printf '/^gdm:x\na\n%s\n.\nw\nq\n' \ + "$XVM_LIN" | ed -s $dest > /dev/null + fi + fi done diff --git a/usr/src/pkgdefs/common_files/i.shadow b/usr/src/pkgdefs/common_files/i.shadow index 46e2dde8ab..721774e579 100644 --- a/usr/src/pkgdefs/common_files/i.shadow +++ b/usr/src/pkgdefs/common_files/i.shadow @@ -139,6 +139,17 @@ do printf '/^nuucp:NP\na\n%s\n.\nw\nq\n' \ "$DLADM_LINE" | ed -s $dest > /dev/null fi + + # + # Add the 'xvm' reserved user if it doesn't exist. + # + XVM_LINE="xvm:*LK*:::::::" + if grep "^xvm:" $dest 2>&1 >/dev/null; then + : + else + printf '/^gdm:\*LK\*\na\n%s\n.\nw\nq\n' \ + "$XVM_LINE" | ed -s $dest > /dev/null + fi fi done diff --git a/usr/src/tools/scripts/bfu.sh b/usr/src/tools/scripts/bfu.sh index 331352fae5..81f5daf515 100644 --- a/usr/src/tools/scripts/bfu.sh +++ b/usr/src/tools/scripts/bfu.sh @@ -7516,6 +7516,11 @@ mondo_loop() { rm -f $rootprefix/etc/datalink.conf fi + # + # Force xVM privilege fixups to occur on next boot. + # + rm -f $rootprefix/var/lib/xend/.xvmuser + print "\nRestoring configuration files.\n" cd $root diff --git a/usr/src/uts/common/os/policy.c b/usr/src/uts/common/os/policy.c index 2333681763..5d7eac6b1c 100644 --- a/usr/src/uts/common/os/policy.c +++ b/usr/src/uts/common/os/policy.c @@ -2221,3 +2221,21 @@ secpolicy_smbfs_login(const cred_t *cr, uid_t uid) return (PRIV_POLICY(cr, PRIV_PROC_OWNER, B_FALSE, EPERM, NULL)); } + +/* + * secpolicy_xvm_control + * + * Determines if a caller can control the xVM hypervisor and/or running + * domains (x86 specific). + * + * Returns: + * 0 access is allowed. + * EPERM access is NOT allowed. + */ +int +secpolicy_xvm_control(const cred_t *cr) +{ + if (PRIV_POLICY(cr, PRIV_XVM_CONTROL, B_FALSE, EPERM, NULL)) + return (EPERM); + return (0); +} diff --git a/usr/src/uts/common/os/priv_defs b/usr/src/uts/common/os/priv_defs index 29467467d1..bd4866f926 100644 --- a/usr/src/uts/common/os/priv_defs +++ b/usr/src/uts/common/os/priv_defs @@ -41,6 +41,7 @@ privilege PRIV_CONTRACT_EVENT any event queue. privilege PRIV_CONTRACT_IDENTITY + Allows a process to set the service FMRI value of a process contract template. @@ -439,6 +440,11 @@ privilege PRIV_SYS_TRANS_LABEL This privilege is interpreted only if the system is configured with Trusted Extensions. +privilege PRIV_VIRT_MANAGE + + Allows a process to manage virtualized environments such as + xVM(5). + privilege PRIV_WIN_COLORMAP Allows a process to override colormap restrictions. @@ -541,6 +547,12 @@ privilege PRIV_WIN_UPGRADE_SL This privilege is interpreted only if the system is configured with Trusted Extensions. +privilege PRIV_XVM_CONTROL + + Allows a process access to the xVM(5) control devices for + managing guest domains and the hypervisor. This privilege is + used only if booted into xVM on x86 platforms. + set PRIV_EFFECTIVE Set of privileges currently in effect. diff --git a/usr/src/uts/common/sys/policy.h b/usr/src/uts/common/sys/policy.h index fa1240845e..fb8d502588 100644 --- a/usr/src/uts/common/sys/policy.h +++ b/usr/src/uts/common/sys/policy.h @@ -161,6 +161,7 @@ void secpolicy_fs_mount_clearopts(cred_t *, struct vfs *); int secpolicy_setid_setsticky_clear(vnode_t *, vattr_t *, const vattr_t *, cred_t *); int secpolicy_xvattr(xvattr_t *, uid_t, cred_t *, vtype_t); +int secpolicy_xvm_control(const cred_t *); int secpolicy_basic_exec(const cred_t *, vnode_t *); int secpolicy_basic_fork(const cred_t *); diff --git a/usr/src/uts/common/xen/io/evtchn_dev.c b/usr/src/uts/common/xen/io/evtchn_dev.c index e963cde835..998fa569f0 100644 --- a/usr/src/uts/common/xen/io/evtchn_dev.c +++ b/usr/src/uts/common/xen/io/evtchn_dev.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -74,6 +74,7 @@ #include <sys/cpu.h> #include <sys/cmn_err.h> #include <sys/xen_errno.h> +#include <sys/policy.h> #include <xen/sys/evtchn.h> /* Some handy macros */ @@ -158,7 +159,7 @@ done: /* ARGSUSED */ static int -evtchndrv_read(dev_t dev, struct uio *uio, cred_t *cred) +evtchndrv_read(dev_t dev, struct uio *uio, cred_t *cr) { int rc = 0; ssize_t count; @@ -166,6 +167,9 @@ evtchndrv_read(dev_t dev, struct uio *uio, cred_t *cred) struct evtsoftdata *ep; minor_t minor = getminor(dev); + if (secpolicy_xvm_control(cr)) + return (EPERM); + ep = EVTCHNDRV_INST2SOFTS(EVTCHNDRV_MINOR2INST(minor)); /* Whole number of ports. */ @@ -231,7 +235,7 @@ done: /* ARGSUSED */ static int -evtchndrv_write(dev_t dev, struct uio *uio, cred_t *cred) +evtchndrv_write(dev_t dev, struct uio *uio, cred_t *cr) { int rc, i; ssize_t count; @@ -240,6 +244,9 @@ evtchndrv_write(dev_t dev, struct uio *uio, cred_t *cred) ulong_t flags; minor_t minor = getminor(dev); + if (secpolicy_xvm_control(cr)) + return (EPERM); + ep = EVTCHNDRV_INST2SOFTS(EVTCHNDRV_MINOR2INST(minor)); kbuf = kmem_alloc(PAGESIZE, KM_SLEEP); @@ -320,13 +327,16 @@ evtchndrv_close_evtchn(int port) /* ARGSUSED */ static int -evtchndrv_ioctl(dev_t dev, int cmd, intptr_t data, int flag, cred_t *cred, +evtchndrv_ioctl(dev_t dev, int cmd, intptr_t data, int flag, cred_t *cr, int *rvalp) { int err = 0; struct evtsoftdata *ep; minor_t minor = getminor(dev); + if (secpolicy_xvm_control(cr)) + return (EPERM); + ep = EVTCHNDRV_INST2SOFTS(EVTCHNDRV_MINOR2INST(minor)); *rvalp = 0; diff --git a/usr/src/uts/common/xen/io/xenbus_dev.c b/usr/src/uts/common/xen/io/xenbus_dev.c index 0eb82322b0..6d40860151 100644 --- a/usr/src/uts/common/xen/io/xenbus_dev.c +++ b/usr/src/uts/common/xen/io/xenbus_dev.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -71,6 +71,8 @@ #include <sys/condvar.h> #include <sys/ddi.h> #include <sys/sunddi.h> +#include <sys/policy.h> + #ifdef XPV_HVM_DRIVER #include <public/io/xenbus.h> #include <public/io/xs_wire.h> @@ -138,6 +140,8 @@ static int xenbusdrv_read(dev_t, struct uio *, cred_t *); static int xenbusdrv_write(dev_t, struct uio *, cred_t *); static int xenbusdrv_devmap(dev_t, devmap_cookie_t, offset_t, size_t, size_t *, uint_t); +static int xenbusdrv_segmap(dev_t, off_t, ddi_as_handle_t, caddr_t *, off_t, + uint_t, uint_t, uint_t, cred_t *); static int xenbusdrv_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); static int xenbusdrv_queue_reply(xenbus_dev_t *, const struct xsd_sockmsg *, const char *); @@ -155,7 +159,7 @@ static struct cb_ops xenbusdrv_cb_ops = { xenbusdrv_ioctl, /* cb_ioctl */ xenbusdrv_devmap, /* cb_devmap */ NULL, /* cb_mmap */ - NULL, /* cb_segmap */ + xenbusdrv_segmap, /* cb_segmap */ nochpoll, /* cb_chpoll */ ddi_prop_op, /* cb_prop_op */ 0, /* cb_stream */ @@ -329,7 +333,7 @@ xenbusdrv_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) /* ARGSUSED */ static int -xenbusdrv_open(dev_t *devp, int flag, int otyp, cred_t *credp) +xenbusdrv_open(dev_t *devp, int flag, int otyp, cred_t *cr) { xenbus_dev_t *xbs; minor_t minor = getminor(*devp); @@ -384,7 +388,7 @@ xenbusdrv_open(dev_t *devp, int flag, int otyp, cred_t *credp) /* ARGSUSED */ static int -xenbusdrv_close(dev_t dev, int flag, int otyp, struct cred *credp) +xenbusdrv_close(dev_t dev, int flag, int otyp, struct cred *cr) { xenbus_dev_t *xbs; minor_t minor = getminor(dev); @@ -431,7 +435,7 @@ xenbusdrv_close(dev_t dev, int flag, int otyp, struct cred *credp) /* ARGSUSED */ static int -xenbusdrv_read(dev_t dev, struct uio *uiop, cred_t *credp) +xenbusdrv_read(dev_t dev, struct uio *uiop, cred_t *cr) { xenbus_dev_t *xbs; size_t len; @@ -440,6 +444,9 @@ xenbusdrv_read(dev_t dev, struct uio *uiop, cred_t *credp) XENBUSDRV_DBPRINT((CE_NOTE, "xenbusdrv_read called")); + if (secpolicy_xvm_control(cr)) + return (EPERM); + xbs = XENBUSDRV_INST2SOFTS(XENBUSDRV_MINOR2INST(getminor(dev))); mutex_enter(&xbs->read_mutex); @@ -512,7 +519,7 @@ xenbusdrv_queue_reply(xenbus_dev_t *xbs, const struct xsd_sockmsg *msg, /* ARGSUSED */ static int -xenbusdrv_write(dev_t dev, struct uio *uiop, cred_t *credp) +xenbusdrv_write(dev_t dev, struct uio *uiop, cred_t *cr) { xenbus_dev_t *xbs; struct xenbus_dev_transaction *trans; @@ -522,6 +529,9 @@ xenbusdrv_write(dev_t dev, struct uio *uiop, cred_t *credp) XENBUSDRV_DBPRINT((CE_NOTE, "xenbusdrv_write called")); + if (secpolicy_xvm_control(cr)) + return (EPERM); + xbs = XENBUSDRV_INST2SOFTS(XENBUSDRV_MINOR2INST(getminor(dev))); len = uiop->uio_resid; @@ -628,13 +638,28 @@ xenbusdrv_devmap(dev_t dev, devmap_cookie_t dhp, offset_t off, size_t len, return (0); } +static int +xenbusdrv_segmap(dev_t dev, off_t off, ddi_as_handle_t as, caddr_t *addrp, + off_t len, uint_t prot, uint_t maxprot, uint_t flags, cred_t *cr) +{ + + if (secpolicy_xvm_control(cr)) + return (EPERM); + + return (ddi_devmap_segmap(dev, off, as, addrp, len, prot, + maxprot, flags, cr)); +} + /*ARGSUSED*/ static int -xenbusdrv_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, +xenbusdrv_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cr, int *rvalp) { xenbus_dev_t *xbs; + if (secpolicy_xvm_control(cr)) + return (EPERM); + xbs = XENBUSDRV_INST2SOFTS(XENBUSDRV_MINOR2INST(getminor(dev))); switch (cmd) { case IOCTL_XENBUS_XENSTORE_EVTCHN: diff --git a/usr/src/uts/i86xpv/io/privcmd.c b/usr/src/uts/i86xpv/io/privcmd.c index 7a3672e5d7..0a40c82e5d 100644 --- a/usr/src/uts/i86xpv/io/privcmd.c +++ b/usr/src/uts/i86xpv/io/privcmd.c @@ -40,6 +40,7 @@ #include <sys/sdt.h> #include <sys/hypervisor.h> #include <sys/xen_errno.h> +#include <sys/policy.h> #include <vm/hat_i86.h> #include <vm/hat_pte.h> @@ -271,12 +272,14 @@ done: static int privcmd_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cr, int *rval) { - if ((mode & FMODELS) != FNATIVE) - return (EOVERFLOW); + if (secpolicy_xvm_control(cr)) + return (EPERM); /* * Everything is a -native- data type. */ + if ((mode & FMODELS) != FNATIVE) + return (EOVERFLOW); switch (cmd) { case IOCTL_PRIVCMD_HYPERCALL: @@ -306,6 +309,9 @@ privcmd_segmap(dev_t dev, off_t off, struct as *as, caddr_t *addrp, struct segmf_crargs a; int error; + if (secpolicy_xvm_control(cr)) + return (EPERM); + as_rangelock(as); if ((flags & MAP_FIXED) == 0) { map_addr(addrp, len, (offset_t)off, 0, flags); diff --git a/usr/src/uts/intel/os/minor_perm b/usr/src/uts/intel/os/minor_perm index 7174295fb2..fdc12ce007 100644 --- a/usr/src/uts/intel/os/minor_perm +++ b/usr/src/uts/intel/os/minor_perm @@ -173,3 +173,8 @@ afe:* 0666 root sys mxfe:* 0666 root sys vscan:* 0640 root sys nsmb:* 0666 root sys +balloon:* 0444 root sys +domcaps:* 0444 root sys +evtchn:* 0666 root sys +privcmd:* 0666 root sys +xenbus:* 0666 root sys |