From owner-svn-src-all@freebsd.org Wed May 2 10:19:18 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 99753FC87B8; Wed, 2 May 2018 10:19:18 +0000 (UTC) (envelope-from royger@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 3CD286DB33; Wed, 2 May 2018 10:19:18 +0000 (UTC) (envelope-from royger@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 33ACA7A4C; Wed, 2 May 2018 10:19:18 +0000 (UTC) (envelope-from royger@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w42AJIIP051138; Wed, 2 May 2018 10:19:18 GMT (envelope-from royger@FreeBSD.org) Received: (from royger@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w42AJH6t051136; Wed, 2 May 2018 10:19:17 GMT (envelope-from royger@FreeBSD.org) Message-Id: <201805021019.w42AJH6t051136@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: royger set sender to royger@FreeBSD.org using -f From: =?UTF-8?Q?Roger_Pau_Monn=c3=a9?= Date: Wed, 2 May 2018 10:19:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r333169 - in head/sys: dev/xen/gntdev xen X-SVN-Group: head X-SVN-Commit-Author: royger X-SVN-Commit-Paths: in head/sys: dev/xen/gntdev xen X-SVN-Commit-Revision: 333169 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 May 2018 10:19:18 -0000 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 \