From: Michal Kubecek <mkubecek@suse.cz>
Date: Tue, 7 Sep 2021 01:28:33 +0200
Subject: kabi: mask changes to vhost_dev_init() and struct vhost_dev
Patch-mainline: Never, kabi workaround
References: CVE-2019-3900 bsc#1133374
Backport of mainline commit e82b9b0727ff ("vhost: introduce
vhost_exceeds_weight()")) adds two new members to struct vhost_dev and two
new parameters to vhost_dev_init().
Move new members into two 4-byte holes in struct vhost_dev and hide them
from genksyms. Rename vhost_dev_init() to vhost_dev_init_wt() and create
a wrapper under the original name which passes 0 for weight and byte_weight
(and modify the check in the vhost_exceeds_weight() to handle also zero
dev->weight).
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
---
drivers/vhost/net.c | 6 +++---
drivers/vhost/scsi.c | 4 ++--
drivers/vhost/vhost.c | 15 +++++++++++----
drivers/vhost/vhost.h | 14 +++++++++++---
drivers/vhost/vsock.c | 6 +++---
5 files changed, 30 insertions(+), 15 deletions(-)
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -1276,9 +1276,9 @@ static int vhost_net_open(struct inode *inode, struct file *f)
n->vqs[i].rx_ring = NULL;
vhost_net_buf_init(&n->vqs[i].rxq);
}
- vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX,
- UIO_MAXIOV + VHOST_NET_BATCH,
- VHOST_NET_PKT_WEIGHT, VHOST_NET_WEIGHT);
+ vhost_dev_init_wt(dev, vqs, VHOST_NET_VQ_MAX,
+ UIO_MAXIOV + VHOST_NET_BATCH,
+ VHOST_NET_PKT_WEIGHT, VHOST_NET_WEIGHT);
vhost_poll_init(n->poll + VHOST_NET_VQ_TX, handle_tx_net, POLLOUT, dev);
vhost_poll_init(n->poll + VHOST_NET_VQ_RX, handle_rx_net, POLLIN, dev);
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1438,8 +1438,8 @@ static int vhost_scsi_open(struct inode *inode, struct file *f)
vqs[i] = &vs->vqs[i].vq;
vs->vqs[i].vq.handle_kick = vhost_scsi_handle_kick;
}
- vhost_dev_init(&vs->dev, vqs, VHOST_SCSI_MAX_VQ, UIO_MAXIOV,
- VHOST_SCSI_WEIGHT, 0);
+ vhost_dev_init_wt(&vs->dev, vqs, VHOST_SCSI_MAX_VQ, UIO_MAXIOV,
+ VHOST_SCSI_WEIGHT, 0);
vhost_scsi_init_inflight(vs, NULL);
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -422,7 +422,7 @@ bool vhost_exceeds_weight(struct vhost_virtqueue *vq,
struct vhost_dev *dev = vq->dev;
if ((dev->byte_weight && total_len >= dev->byte_weight) ||
- pkts >= dev->weight) {
+ (dev->weight && pkts >= dev->weight)) {
vhost_poll_queue(&vq->poll);
return true;
}
@@ -431,9 +431,9 @@ bool vhost_exceeds_weight(struct vhost_virtqueue *vq,
}
EXPORT_SYMBOL_GPL(vhost_exceeds_weight);
-void vhost_dev_init(struct vhost_dev *dev,
- struct vhost_virtqueue **vqs, int nvqs,
- int iov_limit, int weight, int byte_weight)
+void vhost_dev_init_wt(struct vhost_dev *dev,
+ struct vhost_virtqueue **vqs, int nvqs,
+ int iov_limit, int weight, int byte_weight)
{
struct vhost_virtqueue *vq;
int i;
@@ -470,6 +470,13 @@ void vhost_dev_init(struct vhost_dev *dev,
POLLIN, dev);
}
}
+EXPORT_SYMBOL_GPL(vhost_dev_init_wt);
+
+void vhost_dev_init(struct vhost_dev *dev,
+ struct vhost_virtqueue **vqs, int nvqs, int iov_limit)
+{
+ vhost_dev_init_wt(dev, vqs, nvqs, iov_limit, 0, 0);
+}
EXPORT_SYMBOL_GPL(vhost_dev_init);
/* Caller should have device mutex */
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -169,6 +169,10 @@ struct vhost_dev {
struct mutex mutex;
struct vhost_virtqueue **vqs;
int nvqs;
+#ifndef __GENKSYMS__
+ /* filling a 4-byte hole */
+ int weight;
+#endif
struct file *log_file;
struct eventfd_ctx *log_ctx;
struct llist_head work_list;
@@ -176,17 +180,21 @@ struct vhost_dev {
struct vhost_umem *umem;
struct vhost_umem *iotlb;
spinlock_t iotlb_lock;
+#ifndef __GENKSYMS__
+ /* filling a 4-byte hole */
+ int byte_weight;
+#endif
struct list_head read_list;
struct list_head pending_list;
wait_queue_head_t wait;
int iov_limit;
- int weight;
- int byte_weight;
};
bool vhost_exceeds_weight(struct vhost_virtqueue *vq, int pkts, int total_len);
void vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue **vqs,
- int nvqs, int iov_limit, int weight, int byte_weight);
+ int nvqs, int iov_limit);
+void vhost_dev_init_wt(struct vhost_dev *, struct vhost_virtqueue **vqs,
+ int nvqs, int iov_limit, int weight, int byte_weight);
long vhost_dev_set_owner(struct vhost_dev *dev);
bool vhost_dev_has_owner(struct vhost_dev *dev);
long vhost_dev_check_owner(struct vhost_dev *);
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -545,9 +545,9 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file)
vsock->vqs[VSOCK_VQ_TX].handle_kick = vhost_vsock_handle_tx_kick;
vsock->vqs[VSOCK_VQ_RX].handle_kick = vhost_vsock_handle_rx_kick;
- vhost_dev_init(&vsock->dev, vqs, ARRAY_SIZE(vsock->vqs),
- UIO_MAXIOV, VHOST_VSOCK_PKT_WEIGHT,
- VHOST_VSOCK_WEIGHT);
+ vhost_dev_init_wt(&vsock->dev, vqs, ARRAY_SIZE(vsock->vqs),
+ UIO_MAXIOV, VHOST_VSOCK_PKT_WEIGHT,
+ VHOST_VSOCK_WEIGHT);
file->private_data = vsock;
spin_lock_init(&vsock->send_pkt_list_lock);