mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
xsa526 - xsa528 for 7.4
-----BEGIN PGP SIGNATURE----- iJEEABYKADkWIQRTLbB6QfY48x44uB6AXGG7T9hjvgUCau38KhsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQgFxhu0/YY77p8gD/fzG/sN1gYAX12ANL3IiV +oJDtr/jYwdo7Cb93QVXV2UBAOsoraPsjHsWTixiPDIDyAc4L1EZgXmwtByZm1I8 xHoB =H3M7 -----END PGP SIGNATURE----- Merge tag 'xsa526-xsa528-7.4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip Pull xen fixes from Juergen Gross: "Fix three UAF issues that can be hit in the Xen netback and blkback drivers when a guest is forcing a teardown of a PV device" * tag 'xsa526-xsa528-7.4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen-blkback: Avoid UAF when reading I/O statistics xen-netback: defer xenvif_mcast_addr_list_free() xen-netback: Fix UAF when reading statistics data
This commit is contained in:
commit
41b77d5dcc
|
|
@ -318,8 +318,10 @@ struct xen_blkif {
|
|||
unsigned int nr_ring_pages;
|
||||
bool multi_ref;
|
||||
/* All rings for this device. */
|
||||
rwlock_t rings_lock;
|
||||
struct xen_blkif_ring *rings;
|
||||
unsigned int nr_rings;
|
||||
|
||||
unsigned long buffer_squeeze_end;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -127,14 +127,23 @@ static void xen_update_blkif_status(struct xen_blkif *blkif)
|
|||
return;
|
||||
}
|
||||
|
||||
static int xen_blkif_alloc_rings(struct xen_blkif *blkif)
|
||||
static int xen_blkif_alloc_rings(struct xen_blkif *blkif,
|
||||
unsigned int nr_rings)
|
||||
{
|
||||
unsigned int r;
|
||||
struct xen_blkif_ring *rings;
|
||||
|
||||
blkif->rings = kzalloc_objs(struct xen_blkif_ring, blkif->nr_rings);
|
||||
if (!blkif->rings)
|
||||
rings = kzalloc_objs(struct xen_blkif_ring, nr_rings);
|
||||
if (!rings)
|
||||
return -ENOMEM;
|
||||
|
||||
write_lock(&blkif->rings_lock);
|
||||
|
||||
blkif->rings = rings;
|
||||
blkif->nr_rings = nr_rings;
|
||||
|
||||
write_unlock(&blkif->rings_lock);
|
||||
|
||||
for (r = 0; r < blkif->nr_rings; r++) {
|
||||
struct xen_blkif_ring *ring = &blkif->rings[r];
|
||||
|
||||
|
|
@ -174,6 +183,7 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid)
|
|||
blkif->domid = domid;
|
||||
atomic_set(&blkif->refcnt, 1);
|
||||
init_completion(&blkif->drain_complete);
|
||||
rwlock_init(&blkif->rings_lock);
|
||||
|
||||
/*
|
||||
* Because freeing back to the cache may be deferred, it is not
|
||||
|
|
@ -268,6 +278,7 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif)
|
|||
struct pending_req *req, *n;
|
||||
unsigned int j, r;
|
||||
bool busy = false;
|
||||
struct xen_blkif_ring *rings;
|
||||
|
||||
for (r = 0; r < blkif->nr_rings; r++) {
|
||||
struct xen_blkif_ring *ring = &blkif->rings[r];
|
||||
|
|
@ -334,10 +345,16 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif)
|
|||
* blkif->rings was allocated in connect_ring, so we should free it in
|
||||
* here.
|
||||
*/
|
||||
kfree(blkif->rings);
|
||||
write_lock(&blkif->rings_lock);
|
||||
|
||||
rings = blkif->rings;
|
||||
blkif->rings = NULL;
|
||||
blkif->nr_rings = 0;
|
||||
|
||||
write_unlock(&blkif->rings_lock);
|
||||
|
||||
kfree(rings);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -385,6 +402,7 @@ void xen_blkif_interface_fini(void)
|
|||
unsigned int i; \
|
||||
unsigned long long result = 0; \
|
||||
\
|
||||
read_lock(&blkif->rings_lock); \
|
||||
if (!blkif->rings) \
|
||||
goto out; \
|
||||
\
|
||||
|
|
@ -395,6 +413,7 @@ void xen_blkif_interface_fini(void)
|
|||
} \
|
||||
\
|
||||
out: \
|
||||
read_unlock(&blkif->rings_lock); \
|
||||
return sprintf(buf, format, result); \
|
||||
} \
|
||||
static DEVICE_ATTR(name, 0444, show_##name, NULL)
|
||||
|
|
@ -1102,8 +1121,7 @@ static int connect_ring(struct backend_info *be)
|
|||
requested_num_queues, xenblk_max_queues);
|
||||
return -ENOSYS;
|
||||
}
|
||||
blkif->nr_rings = requested_num_queues;
|
||||
if (xen_blkif_alloc_rings(blkif))
|
||||
if (xen_blkif_alloc_rings(blkif, requested_num_queues))
|
||||
return -ENOMEM;
|
||||
|
||||
pr_info("%s: using %d queues, protocol %d (%s) %s\n", dev->nodename,
|
||||
|
|
|
|||
|
|
@ -812,8 +812,6 @@ void xenvif_disconnect_data(struct xenvif *vif)
|
|||
|
||||
xenvif_disconnect_queue(queue);
|
||||
}
|
||||
|
||||
xenvif_mcast_addr_list_free(vif);
|
||||
}
|
||||
|
||||
void xenvif_disconnect_ctrl(struct xenvif *vif)
|
||||
|
|
|
|||
|
|
@ -267,6 +267,8 @@ static void backend_disconnect(struct backend_info *be)
|
|||
vif->num_queues = 0;
|
||||
synchronize_net();
|
||||
|
||||
xenvif_mcast_addr_list_free(vif);
|
||||
|
||||
for (queue_index = 0; queue_index < num_queues; ++queue_index)
|
||||
xenvif_deinit_queue(&vif->queues[queue_index]);
|
||||
|
||||
|
|
@ -837,6 +839,7 @@ static void connect(struct backend_info *be)
|
|||
err:
|
||||
if (be->vif->num_queues > 0)
|
||||
xenvif_disconnect_data(be->vif); /* Clean up existing queues */
|
||||
synchronize_net();
|
||||
for (queue_index = 0; queue_index < be->vif->num_queues; ++queue_index)
|
||||
xenvif_deinit_queue(&be->vif->queues[queue_index]);
|
||||
vfree(be->vif->queues);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user