virtio-9p: Make infrastructure for the new security model.
This patch adds required infrastructure for the new security model. - A new configure option for attr/xattr. - if CONFIG_VIRTFS will be defined if both CONFIG_LINUX and CONFIG_ATTR defined. - Defines routines related to both security models. Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
		
							parent
							
								
									9ce56db6f0
								
							
						
					
					
						commit
						758e8e38eb
					
				| @ -35,8 +35,8 @@ net-nested-$(CONFIG_SLIRP) += slirp.o | ||||
| net-nested-$(CONFIG_VDE) += vde.o | ||||
| net-obj-y += $(addprefix net/, $(net-nested-y)) | ||||
| 
 | ||||
| fsdev-nested-$(CONFIG_LINUX) = qemu-fsdev.o | ||||
| fsdev-obj-$(CONFIG_LINUX) += $(addprefix fsdev/, $(fsdev-nested-y)) | ||||
| fsdev-nested-$(CONFIG_VIRTFS) = qemu-fsdev.o | ||||
| fsdev-obj-$(CONFIG_VIRTFS) += $(addprefix fsdev/, $(fsdev-nested-y)) | ||||
| 
 | ||||
| ######################################################################
 | ||||
| # libqemu_common.a: Target independent part of system emulation. The
 | ||||
| @ -233,7 +233,7 @@ sound-obj-$(CONFIG_CS4231A) += cs4231a.o | ||||
| adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0 | ||||
| hw-obj-$(CONFIG_SOUND) += $(sound-obj-y) | ||||
| 
 | ||||
| hw-obj-$(CONFIG_LINUX) += virtio-9p-debug.o virtio-9p-local.o | ||||
| hw-obj-$(CONFIG_VIRTFS) += virtio-9p-debug.o virtio-9p-local.o | ||||
| 
 | ||||
| ######################################################################
 | ||||
| # libdis
 | ||||
|  | ||||
| @ -169,7 +169,7 @@ obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o | ||||
| obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o | ||||
| obj-y += vhost_net.o | ||||
| obj-$(CONFIG_VHOST_NET) += vhost.o | ||||
| obj-$(CONFIG_LINUX) += virtio-9p.o | ||||
| obj-$(CONFIG_VIRTFS) += virtio-9p.o | ||||
| obj-y += rwhandler.o | ||||
| obj-$(CONFIG_KVM) += kvm.o kvm-all.o | ||||
| obj-$(CONFIG_NO_KVM) += kvm-stub.o | ||||
|  | ||||
							
								
								
									
										37
									
								
								configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								configure
									
									
									
									
										vendored
									
									
								
							| @ -270,6 +270,7 @@ vnc_tls="" | ||||
| vnc_sasl="" | ||||
| xen="" | ||||
| linux_aio="" | ||||
| attr="" | ||||
| vhost_net="" | ||||
| 
 | ||||
| gprof="no" | ||||
| @ -671,6 +672,10 @@ for opt do | ||||
|   ;; | ||||
|   --enable-linux-aio) linux_aio="yes" | ||||
|   ;; | ||||
|   --disable-attr) attr="no" | ||||
|   ;; | ||||
|   --enable-attr) attr="yes" | ||||
|   ;; | ||||
|   --enable-io-thread) io_thread="yes" | ||||
|   ;; | ||||
|   --disable-blobs) blobs="no" | ||||
| @ -858,6 +863,8 @@ echo "  --disable-vde            disable support for vde network" | ||||
| echo "  --enable-vde             enable support for vde network" | ||||
| echo "  --disable-linux-aio      disable Linux AIO support" | ||||
| echo "  --enable-linux-aio       enable Linux AIO support" | ||||
| echo "  --disable-attr           disables attr and xattr support" | ||||
| echo "  --enable-attr            enable attr and xattr support" | ||||
| echo "  --enable-io-thread       enable IO thread" | ||||
| echo "  --disable-blobs          disable installing provided firmware blobs" | ||||
| echo "  --kerneldir=PATH         look for kernel includes in PATH" | ||||
| @ -1645,6 +1652,27 @@ EOF | ||||
|   fi | ||||
| fi | ||||
| 
 | ||||
| ########################################## | ||||
| # attr probe | ||||
| 
 | ||||
| if test "$attr" != "no" ; then | ||||
|   cat > $TMPC <<EOF | ||||
| #include <stdio.h> | ||||
| #include <sys/types.h> | ||||
| #include <attr/xattr.h> | ||||
| int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; } | ||||
| EOF | ||||
|   if compile_prog "" "-lattr" ; then | ||||
|     attr=yes | ||||
|     LIBS="-lattr $LIBS" | ||||
|   else | ||||
|     if test "$attr" = "yes" ; then | ||||
|       feature_not_found "ATTR" | ||||
|     fi | ||||
|     attr=no | ||||
|   fi | ||||
| fi | ||||
| 
 | ||||
| ########################################## | ||||
| # iovec probe | ||||
| cat > $TMPC <<EOF | ||||
| @ -2079,6 +2107,7 @@ echo "PIE user targets  $user_pie" | ||||
| echo "vde support       $vde" | ||||
| echo "IO thread         $io_thread" | ||||
| echo "Linux AIO support $linux_aio" | ||||
| echo "ATTR/XATTR support $attr" | ||||
| echo "Install blobs     $blobs" | ||||
| echo "KVM support       $kvm" | ||||
| echo "fdt support       $fdt" | ||||
| @ -2280,6 +2309,14 @@ fi | ||||
| if test "$linux_aio" = "yes" ; then | ||||
|   echo "CONFIG_LINUX_AIO=y" >> $config_host_mak | ||||
| fi | ||||
| if test "$attr" = "yes" ; then | ||||
|   echo "CONFIG_ATTR=y" >> $config_host_mak | ||||
| fi | ||||
| if test "$linux" = "yes" ; then | ||||
|   if test "$attr" = "yes" ; then | ||||
|     echo "CONFIG_VIRTFS=y" >> $config_host_mak | ||||
|   fi | ||||
| fi | ||||
| if test "$blobs" = "yes" ; then | ||||
|   echo "INSTALL_BLOBS=yes" >> $config_host_mak | ||||
| fi | ||||
|  | ||||
| @ -18,13 +18,33 @@ | ||||
| #include <utime.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/uio.h> | ||||
| #include <sys/vfs.h> | ||||
| #define SM_LOCAL_MODE_BITS    0600 | ||||
| #define SM_LOCAL_DIR_MODE_BITS    0700 | ||||
| 
 | ||||
| typedef enum | ||||
| { | ||||
|     SM_PASSTHROUGH = 1, /* uid/gid set on fileserver files */ | ||||
|     SM_MAPPED,  /* uid/gid part of xattr */ | ||||
| } SecModel; | ||||
| 
 | ||||
| typedef struct FsCred | ||||
| { | ||||
|     uid_t   fc_uid; | ||||
|     gid_t   fc_gid; | ||||
|     mode_t  fc_mode; | ||||
|     dev_t   fc_rdev; | ||||
| } FsCred; | ||||
| 
 | ||||
| typedef struct FsContext | ||||
| { | ||||
|     char *fs_root; | ||||
|     SecModel fs_sm; | ||||
|     uid_t uid; | ||||
| } FsContext; | ||||
| 
 | ||||
| extern void cred_init(FsCred *); | ||||
| 
 | ||||
| typedef struct FileOperations | ||||
| { | ||||
|     int (*lstat)(FsContext *, const char *, struct stat *); | ||||
|  | ||||
| @ -17,6 +17,7 @@ | ||||
| #include <grp.h> | ||||
| #include <sys/socket.h> | ||||
| #include <sys/un.h> | ||||
| #include <attr/xattr.h> | ||||
| 
 | ||||
| static const char *rpath(FsContext *ctx, const char *path) | ||||
| { | ||||
| @ -31,45 +32,37 @@ static int local_lstat(FsContext *ctx, const char *path, struct stat *stbuf) | ||||
|     return lstat(rpath(ctx, path), stbuf); | ||||
| } | ||||
| 
 | ||||
| static int local_setuid(FsContext *ctx, uid_t uid) | ||||
| static int local_set_xattr(const char *path, FsCred *credp) | ||||
| { | ||||
|     struct passwd *pw; | ||||
|     gid_t groups[33]; | ||||
|     int ngroups; | ||||
|     static uid_t cur_uid = -1; | ||||
| 
 | ||||
|     if (cur_uid == uid) { | ||||
|         return 0; | ||||
|     int err; | ||||
|     if (credp->fc_uid != -1) { | ||||
|         err = setxattr(path, "user.virtfs.uid", &credp->fc_uid, sizeof(uid_t), | ||||
|                 0); | ||||
|         if (err) { | ||||
|             return err; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (setreuid(0, 0)) { | ||||
|         return -1; | ||||
|     if (credp->fc_gid != -1) { | ||||
|         err = setxattr(path, "user.virtfs.gid", &credp->fc_gid, sizeof(gid_t), | ||||
|                 0); | ||||
|         if (err) { | ||||
|             return err; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pw = getpwuid(uid); | ||||
|     if (pw == NULL) { | ||||
|         return -1; | ||||
|     if (credp->fc_mode != -1) { | ||||
|         err = setxattr(path, "user.virtfs.mode", &credp->fc_mode, | ||||
|                 sizeof(mode_t), 0); | ||||
|         if (err) { | ||||
|             return err; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     ngroups = 33; | ||||
|     if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups) == -1) { | ||||
|         return -1; | ||||
|     if (credp->fc_rdev != -1) { | ||||
|         err = setxattr(path, "user.virtfs.rdev", &credp->fc_rdev, | ||||
|                 sizeof(dev_t), 0); | ||||
|         if (err) { | ||||
|             return err; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (setgroups(ngroups, groups)) { | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     if (setregid(-1, pw->pw_gid)) { | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     if (setreuid(-1, uid)) { | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     cur_uid = uid; | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| @ -183,6 +176,7 @@ static int local_open2(FsContext *ctx, const char *path, int flags, mode_t mode) | ||||
|     return open(rpath(ctx, path), flags, mode); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static int local_symlink(FsContext *ctx, const char *oldpath, | ||||
|                             const char *newpath) | ||||
| { | ||||
| @ -259,12 +253,13 @@ static int local_remove(FsContext *ctx, const char *path) | ||||
| 
 | ||||
| static int local_fsync(FsContext *ctx, int fd) | ||||
| { | ||||
|     if (0) /* Just to supress the warning. Will be removed in next patch. */ | ||||
|         (void)local_set_xattr(NULL, NULL); | ||||
|     return fsync(fd); | ||||
| } | ||||
| 
 | ||||
| FileOperations local_ops = { | ||||
|     .lstat = local_lstat, | ||||
|     .setuid = local_setuid, | ||||
|     .readlink = local_readlink, | ||||
|     .close = local_close, | ||||
|     .closedir = local_closedir, | ||||
|  | ||||
| @ -67,16 +67,19 @@ static int omode_to_uflags(int8_t mode) | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| void cred_init(FsCred *credp) | ||||
| { | ||||
|     credp->fc_uid = -1; | ||||
|     credp->fc_gid = -1; | ||||
|     credp->fc_mode = -1; | ||||
|     credp->fc_rdev = -1; | ||||
| } | ||||
| 
 | ||||
| static int v9fs_do_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf) | ||||
| { | ||||
|     return s->ops->lstat(&s->ctx, path->data, stbuf); | ||||
| } | ||||
| 
 | ||||
| static int v9fs_do_setuid(V9fsState *s, uid_t uid) | ||||
| { | ||||
|     return s->ops->setuid(&s->ctx, uid); | ||||
| } | ||||
| 
 | ||||
| static ssize_t v9fs_do_readlink(V9fsState *s, V9fsString *path, V9fsString *buf) | ||||
| { | ||||
|     ssize_t len; | ||||
| @ -348,7 +351,6 @@ static V9fsFidState *lookup_fid(V9fsState *s, int32_t fid) | ||||
| 
 | ||||
|     for (f = s->fid_list; f; f = f->next) { | ||||
|         if (f->fid == fid) { | ||||
|             v9fs_do_setuid(s, f->uid); | ||||
|             return f; | ||||
|         } | ||||
|     } | ||||
| @ -2253,8 +2255,15 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf) | ||||
|         exit(1); | ||||
|     } | ||||
| 
 | ||||
|     if (!strcmp(fse->security_model, "passthrough") && | ||||
|                 !strcmp(fse->security_model, "mapped")) { | ||||
|     if (!strcmp(fse->security_model, "passthrough")) { | ||||
|         /* Files on the Fileserver set to client user credentials */ | ||||
|         s->ctx.fs_sm = SM_PASSTHROUGH; | ||||
|     } else if (!strcmp(fse->security_model, "mapped")) { | ||||
|         /* Files on the fileserver are set to QEMU credentials.
 | ||||
|          * Client user credentials are saved in extended attributes. | ||||
|          */ | ||||
|         s->ctx.fs_sm = SM_MAPPED; | ||||
|     } else { | ||||
|         /* user haven't specified a correct security option */ | ||||
|         fprintf(stderr, "one of the following must be specified as the" | ||||
|                 "security option:\n\t security_model=passthrough \n\t " | ||||
|  | ||||
| @ -641,7 +641,7 @@ static int virtio_balloon_init_pci(PCIDevice *pci_dev) | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_LINUX | ||||
| #ifdef CONFIG_VIRTFS | ||||
| static int virtio_9p_init_pci(PCIDevice *pci_dev) | ||||
| { | ||||
|     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); | ||||
| @ -712,7 +712,7 @@ static PCIDeviceInfo virtio_info[] = { | ||||
|         }, | ||||
|         .qdev.reset = virtio_pci_reset, | ||||
|     },{ | ||||
| #ifdef CONFIG_LINUX | ||||
| #ifdef CONFIG_VIRTFS | ||||
|         .qdev.name = "virtio-9p-pci", | ||||
|         .qdev.size = sizeof(VirtIOPCIProxy), | ||||
|         .init      = virtio_9p_init_pci, | ||||
|  | ||||
							
								
								
									
										8
									
								
								vl.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								vl.c
									
									
									
									
									
								
							| @ -147,7 +147,7 @@ int main(int argc, char **argv) | ||||
| #include "qemu-config.h" | ||||
| #include "qemu-objects.h" | ||||
| #include "qemu-options.h" | ||||
| #ifdef CONFIG_LINUX | ||||
| #ifdef CONFIG_VIRTFS | ||||
| #include "fsdev/qemu-fsdev.h" | ||||
| #endif | ||||
| 
 | ||||
| @ -1532,7 +1532,7 @@ static int chardev_init_func(QemuOpts *opts, void *opaque) | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_LINUX | ||||
| #ifdef CONFIG_VIRTFS | ||||
| static int fsdev_init_func(QemuOpts *opts, void *opaque) | ||||
| { | ||||
|     int ret; | ||||
| @ -2281,7 +2281,7 @@ int main(int argc, char **argv, char **envp) | ||||
|                     exit(1); | ||||
|                 } | ||||
|                 break; | ||||
| #ifdef CONFIG_LINUX | ||||
| #ifdef CONFIG_VIRTFS | ||||
|             case QEMU_OPTION_fsdev: | ||||
|                 opts = qemu_opts_parse(&qemu_fsdev_opts, optarg, 1); | ||||
|                 if (!opts) { | ||||
| @ -2705,7 +2705,7 @@ int main(int argc, char **argv, char **envp) | ||||
| 
 | ||||
|     if (qemu_opts_foreach(&qemu_chardev_opts, chardev_init_func, NULL, 1) != 0) | ||||
|         exit(1); | ||||
| #ifdef CONFIG_LINUX | ||||
| #ifdef CONFIG_VIRTFS | ||||
|     if (qemu_opts_foreach(&qemu_fsdev_opts, fsdev_init_func, NULL, 1) != 0) { | ||||
|         exit(1); | ||||
|     } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Venkateswararao Jujjuri (JV)
						Venkateswararao Jujjuri (JV)