Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e07f06f6 authored by Jan Beulich's avatar Jan Beulich Committed by Greg Kroah-Hartman
Browse files

Xen/gntdev: correct error checking in gntdev_map_grant_pages()



commit ebee0eab08594b2bd5db716288a4f1ae5936e9bc upstream.

Failure of the kernel part of the mapping operation should also be
indicated as an error to the caller, or else it may assume the
respective kernel VA is okay to access.

Furthermore gnttab_map_refs() failing still requires recording
successfully mapped handles, so they can be unmapped subsequently. This
in turn requires there to be a way to tell full hypercall failure from
partial success - preset map_op status fields such that they won't
"happen" to look as if the operation succeeded.

Also again use GNTST_okay instead of implying its value (zero).

This is part of XSA-361.

Signed-off-by: default avatarJan Beulich <jbeulich@suse.com>
Cc: stable@vger.kernel.org
Reviewed-by: default avatarJuergen Gross <jgross@suse.com>
Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ba75f439
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -348,21 +348,22 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map)
	pr_debug("map %d+%d\n", map->index, map->count);
	err = gnttab_map_refs(map->map_ops, use_ptemod ? map->kmap_ops : NULL,
			map->pages, map->count);
	if (err)
		return err;

	for (i = 0; i < map->count; i++) {
		if (map->map_ops[i].status) {
		if (map->map_ops[i].status == GNTST_okay)
			map->unmap_ops[i].handle = map->map_ops[i].handle;
		else if (!err)
			err = -EINVAL;
			continue;
		}

		if (map->flags & GNTMAP_device_map)
			map->unmap_ops[i].dev_bus_addr = map->map_ops[i].dev_bus_addr;

		map->unmap_ops[i].handle = map->map_ops[i].handle;
		if (use_ptemod)
		if (use_ptemod) {
			if (map->kmap_ops[i].status == GNTST_okay)
				map->kunmap_ops[i].handle = map->kmap_ops[i].handle;
			else if (!err)
				err = -EINVAL;
		}
	}
	return err;
}
+1 −0
Original line number Diff line number Diff line
@@ -157,6 +157,7 @@ gnttab_set_map_op(struct gnttab_map_grant_ref *map, phys_addr_t addr,
	map->flags = flags;
	map->ref = ref;
	map->dom = domid;
	map->status = 1; /* arbitrary positive value */
}

static inline void