[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v7] run QEMU as non-root
On Fri, 7 Aug 2015, Wei Liu wrote: > On Thu, Jul 23, 2015 at 06:08:02PM +0100, Stefano Stabellini wrote: > [...] > > +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 > > + > > +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) and 2) fail, libxl will use a single user for > ^^^^^^^^^^^^^^ > This is 2) right > > +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 efc0617..3f4283f 100644 > > --- a/tools/libxl/libxl.h > > +++ b/tools/libxl/libxl.h > > @@ -192,6 +192,12 @@ > > * is not present, instead of ERROR_INVAL. > > */ > > #define LIBXL_HAVE_ERROR_DOMAIN_NOTFOUND 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 ABI compatibility > > * > > diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c > > index 0c6408d..24c43df 100644 > > --- a/tools/libxl/libxl_dm.c > > +++ b/tools/libxl/libxl_dm.c > > @@ -19,6 +19,8 @@ > > > > #include "libxl_internal.h" > > #include <xen/hvm/e820.h> > > +#include <sys/types.h> > > +#include <pwd.h> > > > > static const char *libxl_tapif_script(libxl__gc *gc) > > { > > @@ -418,6 +420,33 @@ static char *dm_spice_options(libxl__gc *gc, > > return opt; > > } > > > > +/* return 1 if the user was found, 0 if it was not, -1 on error */ > > +static int libxl__dm_runas_helper(libxl__gc *gc, char *username) > > const char * ok > > +{ > > + struct passwd pwd, *user = NULL; > > + char *buf = NULL; > > + long buf_size; > > + > > + 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 -1; > > + } > > + > > +retry: > > + buf = libxl__realloc(gc, buf, buf_size); > > This should be libxl__alloc and placed out of the loop? But the point is that buf can be increase by 128 bytes chunks in following iterations. How can I do that if I place it outside the loop? > > + errno = 0; > > + getpwnam_r(username, &pwd, buf, buf_size, &user); > > + if (user != NULL) > > + return 1; > > + if (errno == ERANGE) { > > + buf_size += 128; > > + goto retry; > > + } > > Please use for / while to loop. The goto retry loop is a very common patter for error handling, but I can turn it into a loop if you are keen on it. > Also you might want to save and restore errno. Across the getpwnam_r call? Or across the loop? Or across the function libxl__dm_runas_helper? > > + return 0; > > +} > > + > > static char ** libxl__build_device_model_args_new(libxl__gc *gc, > > const char *dm, int guest_domid, > > const libxl_domain_config > > *guest_config, > > @@ -439,6 +468,7 @@ static char ** > > libxl__build_device_model_args_new(libxl__gc *gc, > > int i, connection, devid; > > uint64_t ram_size; > > const char *path, *chardev; > > + char *user = NULL; > > > > dm_args = flexarray_make(gc, 16, 1); > > > > @@ -878,6 +908,31 @@ static char ** > > 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); > > + if (libxl__dm_runas_helper(gc, user) > 0) > > + goto end_search; > > You haven't checked if libxl__dm_runas_helper returns -1. In that case > we should bail? Yes, I think return NULL would be OK. > > + > > + user = LIBXL_QEMU_USER_SHARED; > > + if (libxl__dm_runas_helper(gc, user) > 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); > > + > > Line too long. > > Wei. > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |