Commit 7d767a95 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-linus-6.17-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip

Pull xen updates from Juergen Gross:

 - fix for a UAF in the xen gntdev-dmabuf driver

 - fix in the xen netfront driver avoiding spurious interrupts

 - fix in the gntdev driver avoiding a large stack allocation

 - cleanup removing some dead code

 - build warning fix

 - cleanup of the sysfs code in the xen-pciback driver

* tag 'for-linus-6.17-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
  xen/netfront: Fix TX response spurious interrupts
  xen/gntdev: remove struct gntdev_copy_batch from stack
  xen: fix UAF in dmabuf_exp_from_pages()
  xen: Remove some deadcode (x)
  xen-pciback: Replace scnprintf() with sysfs_emit_at()
  xen/xenbus: fix W=1 build warning in xenbus_va_dev_error function
parents 2be6a750 114a2de6
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -638,8 +638,6 @@ static int xennet_xdp_xmit_one(struct net_device *dev,
	tx_stats->packets++;
	u64_stats_update_end(&tx_stats->syncp);

	xennet_tx_buf_gc(queue);

	return 0;
}

@@ -849,9 +847,6 @@ static netdev_tx_t xennet_start_xmit(struct sk_buff *skb, struct net_device *dev
	tx_stats->packets++;
	u64_stats_update_end(&tx_stats->syncp);

	/* Note: It is not safe to access skb after xennet_tx_buf_gc()! */
	xennet_tx_buf_gc(queue);

	if (!netfront_tx_slot_available(queue))
		netif_tx_stop_queue(netdev_get_tx_queue(dev, queue->id));

+4 −0
Original line number Diff line number Diff line
@@ -26,6 +26,10 @@ struct gntdev_priv {
	/* lock protects maps and freeable_maps. */
	struct mutex lock;

	/* Free instances of struct gntdev_copy_batch. */
	struct gntdev_copy_batch *batch;
	struct mutex batch_lock;

#ifdef CONFIG_XEN_GRANT_DMA_ALLOC
	/* Device for which DMA memory is allocated. */
	struct device *dma_dev;
+10 −18
Original line number Diff line number Diff line
@@ -357,8 +357,11 @@ struct gntdev_dmabuf_export_args {
static int dmabuf_exp_from_pages(struct gntdev_dmabuf_export_args *args)
{
	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
	struct gntdev_dmabuf *gntdev_dmabuf;
	int ret;
	struct gntdev_dmabuf *gntdev_dmabuf __free(kfree) = NULL;
	CLASS(get_unused_fd, ret)(O_CLOEXEC);

	if (ret < 0)
		return ret;

	gntdev_dmabuf = kzalloc(sizeof(*gntdev_dmabuf), GFP_KERNEL);
	if (!gntdev_dmabuf)
@@ -383,32 +386,21 @@ static int dmabuf_exp_from_pages(struct gntdev_dmabuf_export_args *args)
	exp_info.priv = gntdev_dmabuf;

	gntdev_dmabuf->dmabuf = dma_buf_export(&exp_info);
	if (IS_ERR(gntdev_dmabuf->dmabuf)) {
		ret = PTR_ERR(gntdev_dmabuf->dmabuf);
		gntdev_dmabuf->dmabuf = NULL;
		goto fail;
	}

	ret = dma_buf_fd(gntdev_dmabuf->dmabuf, O_CLOEXEC);
	if (ret < 0)
		goto fail;
	if (IS_ERR(gntdev_dmabuf->dmabuf))
		return PTR_ERR(gntdev_dmabuf->dmabuf);

	gntdev_dmabuf->fd = ret;
	args->fd = ret;

	pr_debug("Exporting DMA buffer with fd %d\n", ret);

	get_file(gntdev_dmabuf->priv->filp);
	mutex_lock(&args->dmabuf_priv->lock);
	list_add(&gntdev_dmabuf->next, &args->dmabuf_priv->exp_list);
	mutex_unlock(&args->dmabuf_priv->lock);
	get_file(gntdev_dmabuf->priv->filp);
	return 0;

fail:
	if (gntdev_dmabuf->dmabuf)
		dma_buf_put(gntdev_dmabuf->dmabuf);
	kfree(gntdev_dmabuf);
	return ret;
	fd_install(take_fd(ret), no_free_ptr(gntdev_dmabuf)->dmabuf->file);
	return 0;
}

static struct gntdev_grant_map *
+50 −21
Original line number Diff line number Diff line
@@ -56,6 +56,18 @@ MODULE_AUTHOR("Derek G. Murray <Derek.Murray@cl.cam.ac.uk>, "
	      "Gerd Hoffmann <kraxel@redhat.com>");
MODULE_DESCRIPTION("User-space granted page access driver");

#define GNTDEV_COPY_BATCH 16

struct gntdev_copy_batch {
	struct gnttab_copy ops[GNTDEV_COPY_BATCH];
	struct page *pages[GNTDEV_COPY_BATCH];
	s16 __user *status[GNTDEV_COPY_BATCH];
	unsigned int nr_ops;
	unsigned int nr_pages;
	bool writeable;
	struct gntdev_copy_batch *next;
};

static unsigned int limit = 64*1024;
module_param(limit, uint, 0644);
MODULE_PARM_DESC(limit,
@@ -584,6 +596,8 @@ static int gntdev_open(struct inode *inode, struct file *flip)
	INIT_LIST_HEAD(&priv->maps);
	mutex_init(&priv->lock);

	mutex_init(&priv->batch_lock);

#ifdef CONFIG_XEN_GNTDEV_DMABUF
	priv->dmabuf_priv = gntdev_dmabuf_init(flip);
	if (IS_ERR(priv->dmabuf_priv)) {
@@ -608,6 +622,7 @@ static int gntdev_release(struct inode *inode, struct file *flip)
{
	struct gntdev_priv *priv = flip->private_data;
	struct gntdev_grant_map *map;
	struct gntdev_copy_batch *batch;

	pr_debug("priv %p\n", priv);

@@ -620,6 +635,14 @@ static int gntdev_release(struct inode *inode, struct file *flip)
	}
	mutex_unlock(&priv->lock);

	mutex_lock(&priv->batch_lock);
	while (priv->batch) {
		batch = priv->batch;
		priv->batch = batch->next;
		kfree(batch);
	}
	mutex_unlock(&priv->batch_lock);

#ifdef CONFIG_XEN_GNTDEV_DMABUF
	gntdev_dmabuf_fini(priv->dmabuf_priv);
#endif
@@ -785,17 +808,6 @@ static long gntdev_ioctl_notify(struct gntdev_priv *priv, void __user *u)
	return rc;
}

#define GNTDEV_COPY_BATCH 16

struct gntdev_copy_batch {
	struct gnttab_copy ops[GNTDEV_COPY_BATCH];
	struct page *pages[GNTDEV_COPY_BATCH];
	s16 __user *status[GNTDEV_COPY_BATCH];
	unsigned int nr_ops;
	unsigned int nr_pages;
	bool writeable;
};

static int gntdev_get_page(struct gntdev_copy_batch *batch, void __user *virt,
				unsigned long *gfn)
{
@@ -953,36 +965,53 @@ static int gntdev_grant_copy_seg(struct gntdev_copy_batch *batch,
static long gntdev_ioctl_grant_copy(struct gntdev_priv *priv, void __user *u)
{
	struct ioctl_gntdev_grant_copy copy;
	struct gntdev_copy_batch batch;
	struct gntdev_copy_batch *batch;
	unsigned int i;
	int ret = 0;

	if (copy_from_user(&copy, u, sizeof(copy)))
		return -EFAULT;

	batch.nr_ops = 0;
	batch.nr_pages = 0;
	mutex_lock(&priv->batch_lock);
	if (!priv->batch) {
		batch = kmalloc(sizeof(*batch), GFP_KERNEL);
	} else {
		batch = priv->batch;
		priv->batch = batch->next;
	}
	mutex_unlock(&priv->batch_lock);
	if (!batch)
		return -ENOMEM;

	batch->nr_ops = 0;
	batch->nr_pages = 0;

	for (i = 0; i < copy.count; i++) {
		struct gntdev_grant_copy_segment seg;

		if (copy_from_user(&seg, &copy.segments[i], sizeof(seg))) {
			ret = -EFAULT;
			gntdev_put_pages(batch);
			goto out;
		}

		ret = gntdev_grant_copy_seg(&batch, &seg, &copy.segments[i].status);
		if (ret < 0)
		ret = gntdev_grant_copy_seg(batch, &seg, &copy.segments[i].status);
		if (ret < 0) {
			gntdev_put_pages(batch);
			goto out;
		}

		cond_resched();
	}
	if (batch.nr_ops)
		ret = gntdev_copy(&batch);
	return ret;
	if (batch->nr_ops)
		ret = gntdev_copy(batch);

 out:
	gntdev_put_pages(&batch);
	mutex_lock(&priv->batch_lock);
	batch->next = priv->batch;
	priv->batch = batch;
	mutex_unlock(&priv->batch_lock);

	return ret;
}

+0 −6
Original line number Diff line number Diff line
@@ -52,12 +52,6 @@ void xen_resume_notifier_register(struct notifier_block *nb)
}
EXPORT_SYMBOL_GPL(xen_resume_notifier_register);

void xen_resume_notifier_unregister(struct notifier_block *nb)
{
	raw_notifier_chain_unregister(&xen_resume_notifier, nb);
}
EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister);

#ifdef CONFIG_HIBERNATE_CALLBACKS
static int xen_suspend(void *data)
{
Loading