svn commit: r333169 - in head/sys: dev/xen/gntdev xen

Roger Pau Monné royger at FreeBSD.org
Wed May 2 10:19:18 UTC 2018


Author: royger
Date: Wed May  2 10:19:17 2018
New Revision: 333169
URL: https://svnweb.freebsd.org/changeset/base/333169

Log:
  xen: fix gntdev
  
  Current interface to the gntdev in FreeBSD is wrong, and mostly worked
  out of luck before the PTI FreeBSD fixes, when kernel and user-space
  where sharing the same page tables.
  
  On FreeBSD ioctls have the size of the passed struct encoded in the
  ioctl number, because the generic ioctl handler in the OS takes care
  of copying the data from user-space to kernel space, and then calls
  the device specific ioctl handler. Thus using ioctl structs with
  variable sizes is not possible.
  
  The fix is to turn the array of structs at the end of
  ioctl_gntdev_alloc_gref and ioctl_gntdev_map_grant_ref into pointers,
  that can be properly accessed from the kernel gntdev driver using the
  copyin/copyout functions. Note that this is exactly how it's done for
  the privcmd driver.
  
  Sponsored by:   Citrix Systems R&D

Modified:
  head/sys/dev/xen/gntdev/gntdev.c
  head/sys/xen/gntdev.h

Modified: head/sys/dev/xen/gntdev/gntdev.c
==============================================================================
--- head/sys/dev/xen/gntdev/gntdev.c	Wed May  2 08:26:59 2018	(r333168)
+++ head/sys/dev/xen/gntdev/gntdev.c	Wed May  2 10:19:17 2018	(r333169)
@@ -414,7 +414,7 @@ gntdev_alloc_gref(struct ioctl_gntdev_alloc_gref *arg)
 	/* Copy the output values. */
 	arg->index = file_offset;
 	for (i = 0; i < arg->count; i++)
-		arg->gref_ids[i] = grefs[i].gref_id;
+		suword32(&arg->gref_ids[i], grefs[i].gref_id);
 
 	/* Modify the per user private data. */
 	mtx_lock(&priv_user->user_data_lock);
@@ -659,16 +659,27 @@ gntdev_map_grant_ref(struct ioctl_gntdev_map_grant_ref
 	gmap->grant_map_ops =
 	    malloc(sizeof(struct gnttab_map_grant_ref) * arg->count,
 	        M_GNTDEV, M_WAITOK | M_ZERO);
-	
-	error = get_file_offset(priv_user, arg->count, &gmap->file_index);
-	if (error != 0)
-		return (error);
 
 	for (i = 0; i < arg->count; i++) {
-		gmap->grant_map_ops[i].dom = arg->refs[i].domid;
-		gmap->grant_map_ops[i].ref = arg->refs[i].ref;
+		struct ioctl_gntdev_grant_ref ref;
+
+		error = copyin(&arg->refs[i], &ref, sizeof(ref));
+		if (error != 0) {
+			free(gmap->grant_map_ops, M_GNTDEV);
+			free(gmap, M_GNTDEV);
+			return (error);
+		}
+		gmap->grant_map_ops[i].dom = ref.domid;
+		gmap->grant_map_ops[i].ref = ref.ref;
 		gmap->grant_map_ops[i].handle = -1;
 		gmap->grant_map_ops[i].flags = GNTMAP_host_map;
+	}
+
+	error = get_file_offset(priv_user, arg->count, &gmap->file_index);
+	if (error != 0) {
+		free(gmap->grant_map_ops, M_GNTDEV);
+		free(gmap, M_GNTDEV);
+		return (error);
 	}
 
 	mtx_lock(&priv_user->user_data_lock);

Modified: head/sys/xen/gntdev.h
==============================================================================
--- head/sys/xen/gntdev.h	Wed May  2 08:26:59 2018	(r333168)
+++ head/sys/xen/gntdev.h	Wed May  2 10:19:17 2018	(r333169)
@@ -139,7 +139,7 @@ struct ioctl_gntdev_alloc_gref {
     /* OUT parameters */
     uint64_t index;
     /* Variable OUT parameter */
-    uint32_t gref_ids[1];
+    uint32_t *gref_ids;
 };
 
 #define GNTDEV_ALLOC_FLAG_WRITABLE 1
@@ -168,7 +168,7 @@ struct ioctl_gntdev_map_grant_ref {
     /* OUT parameters */
     uint64_t index;
     /* Variable IN parameter */
-    struct ioctl_gntdev_grant_ref refs[1];
+    struct ioctl_gntdev_grant_ref *refs;
 };
 
 #define IOCTL_GNTDEV_UNMAP_GRANT_REF					\


More information about the svn-src-head mailing list