[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v10] run QEMU as non-root
On Thu, 2015-11-05 at 12:47 +0000, Stefano Stabellini wrote: > diff --git a/docs/misc/qemu-deprivilege.txt b/docs/misc/qemu- > deprivilege.txt > new file mode 100644 > index 0000000..dde74ab > --- /dev/null > +++ b/docs/misc/qemu-deprivilege.txt > @@ -0,0 +1,31 @@ > +For security reasons, libxl tries to pass a non-root username to QEMU as > +argument. During initialization QEMU calls setuid and setgid with the > +user ID and the group ID of the user passed as argument. > +Libxl looks for the following users in this order: > + > +1) a user named "xen-qemuuser-domid$domid", > +Where $domid is the domid of the domain being created. > +This requires the reservation of 65535 uids from xen-qemuuser-domid1 > +to xen-qemuuser-domid65535. To use this mechanism, you might want to > +create a large number of users at installation time. For example: > + > +for ((i=1; i<65536; i++)) > +do > +ÂÂÂÂadduser --no-create-home --system xen-qemuuser-domid$i > +done I suppose we should integrate either this or suggestion #2 into osstest. Will you send a patch? I suppose ts-xen-install is the obvious place to do this, only quirk might be making it idempotent (for convenience when running in standalone mode). The adduser manpage suggests it already is: Â Â Â Â0ÂÂÂÂÂÂTheÂÂuser exists as specified. This can have 2 causes: ÂÂÂÂÂÂÂÂÂÂÂÂÂÂThe user wasÂÂcreatedÂÂbyÂÂadduserÂÂorÂÂtheÂÂuserÂÂwas ÂÂÂÂÂÂÂÂÂÂÂÂÂÂalreadyÂÂpresentÂÂonÂÂtheÂÂsystemÂÂbeforeÂÂadduser was ÂÂÂÂÂÂÂÂÂÂÂÂÂÂinvoked. If adduser was returning 0 , invoking adduser ÂÂÂÂÂÂÂÂÂÂÂÂÂÂaÂÂsecond time with the same parameters as before also ÂÂÂÂÂÂÂÂÂÂÂÂÂÂreturns 0. So hopefully that is trivial. > > +You might want to consider passing --group to adduser to create a new > +group for each new user. > + > + > +2) a user named "xen-qemuuser-shared" > +As a fall back if both 1) fails, libxl will use a single user for > +all QEMU instances. The user is named xen-qemuuser-shared. This is > +less secure but still better than running QEMU as root. Using this is as > +simple as creating just one more user on your host: > + > +adduser --no-create-home --system xen-qemuuser-shared > + > + > +3) root > +As a last resort, libxl will start QEMU as root. > diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h > index 168fedd..5edeb30 100644 > --- a/tools/libxl/libxl.h > +++ b/tools/libxl/libxl.h > @@ -199,6 +199,11 @@ > Â */ > Â#define LIBXL_HAVE_DEVICETREE_PASSTHROUGH 1 > Â > +/* libxl_domain_build_info has device_model_user to specify the user to > + * run the device model with. See docs/misc/qemu-deprivilege.txt. > + */ > +#define LIBXL_HAVE_DEVICE_MODEL_USER 1 > + > Â/* > Â * libxl_domain_build_info has the arm.gic_version field. > Â */ > diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c > index 9c9eaa3..151b6ed 100644 > --- a/tools/libxl/libxl_dm.c > +++ b/tools/libxl/libxl_dm.c > @@ -21,6 +21,8 @@ > Â > Â#include <xc_dom.h> > Â#include <xen/hvm/e820.h> > +#include <sys/types.h> > +#include <pwd.h> > Â > Âstatic const char *libxl_tapif_script(libxl__gc *gc) > Â{ > @@ -722,6 +724,36 @@ libxl__detect_gfx_passthru_kind(libxl__gc *gc, > ÂÂÂÂÂreturn LIBXL_GFX_PASSTHRU_KIND_DEFAULT; > Â} > Â > +/* return 1 if the user was found, 0 if it was not, -1 on error */ > +static int libxl__dm_runas_helper(libxl__gc *gc, const char *username) > +{ > +ÂÂÂÂstruct passwd pwd, *user = NULL; > +ÂÂÂÂchar *buf = NULL; > +ÂÂÂÂlong buf_size; > +ÂÂÂÂint ret; > + > +ÂÂÂÂbuf_size = sysconf(_SC_GETPW_R_SIZE_MAX); > +ÂÂÂÂif (buf_size < 0) { > +ÂÂÂÂÂÂÂÂLOGE(ERROR, "sysconf(_SC_GETPW_R_SIZE_MAX) returned error %ld", > +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂbuf_size); > +ÂÂÂÂÂÂÂÂreturn ERROR_FAIL; > +ÂÂÂÂ} > + > +ÂÂÂÂwhile (1) { > +ÂÂÂÂÂÂÂÂbuf = libxl__realloc(gc, buf, buf_size); > +ÂÂÂÂÂÂÂÂret = getpwnam_r(username, &pwd, buf, buf_size, &user); > +ÂÂÂÂÂÂÂÂif (ret == ERANGE) { > +ÂÂÂÂÂÂÂÂÂÂÂÂbuf_size += 128; > +ÂÂÂÂÂÂÂÂÂÂÂÂcontinue; > +ÂÂÂÂÂÂÂÂ} > +ÂÂÂÂÂÂÂÂif (ret != 0) > +ÂÂÂÂÂÂÂÂÂÂÂÂreturn ERROR_FAIL; > +ÂÂÂÂÂÂÂÂif (user != NULL) > +ÂÂÂÂÂÂÂÂÂÂÂÂreturn 1; > +ÂÂÂÂÂÂÂÂreturn 0; > +ÂÂÂÂ} > +} > + > Âstatic int libxl__build_device_model_args_new(libxl__gc *gc, > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂconst char *dm, int guest_domid, > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂconst libxl_domain_config > *guest_config, > @@ -740,9 +772,10 @@ static int > libxl__build_device_model_args_new(libxl__gc *gc, > ÂÂÂÂÂconst char *keymap = dm_keymap(guest_config); > ÂÂÂÂÂchar *machinearg; > ÂÂÂÂÂflexarray_t *dm_args, *dm_envs; > -ÂÂÂÂint i, connection, devid; > +ÂÂÂÂint i, connection, devid, ret; > ÂÂÂÂÂuint64_t ram_size; > ÂÂÂÂÂconst char *path, *chardev; > +ÂÂÂÂchar *user = NULL; > Â > ÂÂÂÂÂdm_args = flexarray_make(gc, 16, 1); > ÂÂÂÂÂdm_envs = flexarray_make(gc, 16, 1); > @@ -1222,6 +1255,38 @@ static int > libxl__build_device_model_args_new(libxl__gc *gc, > ÂÂÂÂÂÂÂÂÂdefault: > ÂÂÂÂÂÂÂÂÂÂÂÂÂbreak; > ÂÂÂÂÂÂÂÂÂ} > + > +ÂÂÂÂÂÂÂÂif (b_info->device_model_user) { > +ÂÂÂÂÂÂÂÂÂÂÂÂuser = b_info->device_model_user; > +ÂÂÂÂÂÂÂÂÂÂÂÂgoto end_search; > +ÂÂÂÂÂÂÂÂ} > + > +ÂÂÂÂÂÂÂÂuser = libxl__sprintf(gc, "%s%d", LIBXL_QEMU_USER_BASE, > guest_domid); > +ÂÂÂÂÂÂÂÂret = libxl__dm_runas_helper(gc, user); > +ÂÂÂÂÂÂÂÂif (ret < 0) > +ÂÂÂÂÂÂÂÂÂÂÂÂreturn ret; > +ÂÂÂÂÂÂÂÂif (ret > 0) > +ÂÂÂÂÂÂÂÂÂÂÂÂgoto end_search; > + > +ÂÂÂÂÂÂÂÂuser = LIBXL_QEMU_USER_SHARED; > +ÂÂÂÂÂÂÂÂret = libxl__dm_runas_helper(gc, user); > +ÂÂÂÂÂÂÂÂif (ret < 0) > +ÂÂÂÂÂÂÂÂÂÂÂÂreturn ret; > +ÂÂÂÂÂÂÂÂif (ret > 0) { > +ÂÂÂÂÂÂÂÂÂÂÂÂLOG(WARN, "Could not find user %s%d, falling back to %s", > +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂLIBXL_QEMU_USER_BASE, guest_domid, > LIBXL_QEMU_USER_SHARED); > +ÂÂÂÂÂÂÂÂÂÂÂÂgoto end_search; > +ÂÂÂÂÂÂÂÂ} > + > +ÂÂÂÂÂÂÂÂuser = NULL; > +ÂÂÂÂÂÂÂÂLOG(WARN, "Could not find user %s, starting QEMU as root", > +ÂÂÂÂÂÂÂÂÂÂÂÂLIBXL_QEMU_USER_SHARED); > + > +end_search: > +ÂÂÂÂÂÂÂÂif (user != NULL && strcmp(user, "root")) { > +ÂÂÂÂÂÂÂÂÂÂÂÂflexarray_append(dm_args, "-runas"); > +ÂÂÂÂÂÂÂÂÂÂÂÂflexarray_append(dm_args, user); > +ÂÂÂÂÂÂÂÂ} > ÂÂÂÂÂ} > ÂÂÂÂÂflexarray_append(dm_args, NULL); > ÂÂÂÂÂ*args = (char **) flexarray_contents(dm_args); > diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h > index b00add0..952b668 100644 > --- a/tools/libxl/libxl_internal.h > +++ b/tools/libxl/libxl_internal.h > @@ -4018,6 +4018,11 @@ void libxl__bitmap_copy_best_effort(libxl__gc *gc, > libxl_bitmap *dptr, > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂconst libxl_bitmap *sptr); > Â > Âint libxl__count_physical_sockets(libxl__gc *gc, int *sockets); > + > + > +#define LIBXL_QEMU_USER_PREFIX "xen-qemuuser" > +#define LIBXL_QEMU_USER_BASEÂÂÂLIBXL_QEMU_USER_PREFIX"-domid" > +#define LIBXL_QEMU_USER_SHARED LIBXL_QEMU_USER_PREFIX"-shared" > Â#endif > Â > Â/* > diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl > index 4d78f86..6808f2b 100644 > --- a/tools/libxl/libxl_types.idl > +++ b/tools/libxl/libxl_types.idl > @@ -440,6 +440,7 @@ libxl_domain_build_info = > Struct("domain_build_info",[ > ÂÂÂÂÂ("device_model",ÂÂÂÂÂstring), > ÂÂÂÂÂ("device_model_ssidref", uint32), > ÂÂÂÂÂ("device_model_ssid_label", string), > +ÂÂÂÂ("device_model_user", string), > Â > ÂÂÂÂÂ# extra parameters pass directly to qemu, NULL terminated > ÂÂÂÂÂ("extra",ÂÂÂÂÂÂÂÂÂÂÂÂlibxl_string_list), > diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c > index 03442e1..2b6371d 100644 > --- a/tools/libxl/xl_cmdimpl.c > +++ b/tools/libxl/xl_cmdimpl.c > @@ -2201,6 +2201,9 @@ skip_vfb: > ÂÂÂÂÂÂÂÂÂxlu_cfg_replace_string(config, > "device_model_stubdomain_seclabel", > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ&b_info->device_model_ssid_label, 0); > Â > +ÂÂÂÂxlu_cfg_replace_string(config, "device_model_user", > +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ&b_info->device_model_user, 0); > + > Â#define > parse_extra_args(type)ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ\ > ÂÂÂÂÂe = xlu_cfg_get_list_as_string_list(config, > "device_model_args"#type, \ > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ&b_info->extra##type, > 0);ÂÂÂÂÂÂÂÂÂÂÂÂ\ _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |