Skip to content

Commit e35e5b6

Browse files
committed
Merge tag 'xsa-5.19-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen security fixes from Juergen Gross: - XSA-403 (4 patches for blkfront and netfront drivers): Linux Block and Network PV device frontends don't zero memory regions before sharing them with the backend (CVE-2022-26365, CVE-2022-33740). Additionally the granularity of the grant table doesn't allow sharing less than a 4K page, leading to unrelated data residing in the same 4K page as data shared with a backend being accessible by such backend (CVE-2022-33741, CVE-2022-33742). - XSA-405 (1 patch for netfront driver, only 5.10 and newer): While adding logic to support XDP (eXpress Data Path), a code label was moved in a way allowing for SKBs having references (pointers) retained for further processing to nevertheless be freed. - XSA-406 (1 patch for Arm specific dom0 code): When mapping pages of guests on Arm, dom0 is using an rbtree to keep track of the foreign mappings. Updating of that rbtree is not always done completely with the related lock held, resulting in a small race window, which can be used by unprivileged guests via PV devices to cause inconsistencies of the rbtree. These inconsistencies can lead to Denial of Service (DoS) of dom0, e.g. by causing crashes or the inability to perform further mappings of other guests' memory pages. * tag 'xsa-5.19-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen/arm: Fix race in RB-tree based P2M accounting xen-netfront: restore __skb_queue_tail() positioning in xennet_get_responses() xen/blkfront: force data bouncing when backend is untrusted xen/netfront: force data bouncing when backend is untrusted xen/netfront: fix leaking data in shared pages xen/blkfront: fix leaking data in shared pages
2 parents c1084b6 + b75cd21 commit e35e5b6

File tree

3 files changed

+93
-23
lines changed

3 files changed

+93
-23
lines changed

arch/arm/xen/p2m.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,12 @@ static int xen_add_phys_to_mach_entry(struct xen_p2m_entry *new)
6363

6464
unsigned long __pfn_to_mfn(unsigned long pfn)
6565
{
66-
struct rb_node *n = phys_to_mach.rb_node;
66+
struct rb_node *n;
6767
struct xen_p2m_entry *entry;
6868
unsigned long irqflags;
6969

7070
read_lock_irqsave(&p2m_lock, irqflags);
71+
n = phys_to_mach.rb_node;
7172
while (n) {
7273
entry = rb_entry(n, struct xen_p2m_entry, rbnode_phys);
7374
if (entry->pfn <= pfn &&
@@ -152,10 +153,11 @@ bool __set_phys_to_machine_multi(unsigned long pfn,
152153
int rc;
153154
unsigned long irqflags;
154155
struct xen_p2m_entry *p2m_entry;
155-
struct rb_node *n = phys_to_mach.rb_node;
156+
struct rb_node *n;
156157

157158
if (mfn == INVALID_P2M_ENTRY) {
158159
write_lock_irqsave(&p2m_lock, irqflags);
160+
n = phys_to_mach.rb_node;
159161
while (n) {
160162
p2m_entry = rb_entry(n, struct xen_p2m_entry, rbnode_phys);
161163
if (p2m_entry->pfn <= pfn &&

drivers/block/xen-blkfront.c

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ static unsigned int xen_blkif_max_ring_order;
152152
module_param_named(max_ring_page_order, xen_blkif_max_ring_order, int, 0444);
153153
MODULE_PARM_DESC(max_ring_page_order, "Maximum order of pages to be used for the shared ring");
154154

155+
static bool __read_mostly xen_blkif_trusted = true;
156+
module_param_named(trusted, xen_blkif_trusted, bool, 0644);
157+
MODULE_PARM_DESC(trusted, "Is the backend trusted");
158+
155159
#define BLK_RING_SIZE(info) \
156160
__CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * (info)->nr_ring_pages)
157161

@@ -210,6 +214,7 @@ struct blkfront_info
210214
unsigned int feature_discard:1;
211215
unsigned int feature_secdiscard:1;
212216
unsigned int feature_persistent:1;
217+
unsigned int bounce:1;
213218
unsigned int discard_granularity;
214219
unsigned int discard_alignment;
215220
/* Number of 4KB segments handled */
@@ -310,8 +315,8 @@ static int fill_grant_buffer(struct blkfront_ring_info *rinfo, int num)
310315
if (!gnt_list_entry)
311316
goto out_of_memory;
312317

313-
if (info->feature_persistent) {
314-
granted_page = alloc_page(GFP_NOIO);
318+
if (info->bounce) {
319+
granted_page = alloc_page(GFP_NOIO | __GFP_ZERO);
315320
if (!granted_page) {
316321
kfree(gnt_list_entry);
317322
goto out_of_memory;
@@ -330,7 +335,7 @@ static int fill_grant_buffer(struct blkfront_ring_info *rinfo, int num)
330335
list_for_each_entry_safe(gnt_list_entry, n,
331336
&rinfo->grants, node) {
332337
list_del(&gnt_list_entry->node);
333-
if (info->feature_persistent)
338+
if (info->bounce)
334339
__free_page(gnt_list_entry->page);
335340
kfree(gnt_list_entry);
336341
i--;
@@ -376,7 +381,7 @@ static struct grant *get_grant(grant_ref_t *gref_head,
376381
/* Assign a gref to this page */
377382
gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head);
378383
BUG_ON(gnt_list_entry->gref == -ENOSPC);
379-
if (info->feature_persistent)
384+
if (info->bounce)
380385
grant_foreign_access(gnt_list_entry, info);
381386
else {
382387
/* Grant access to the GFN passed by the caller */
@@ -400,7 +405,7 @@ static struct grant *get_indirect_grant(grant_ref_t *gref_head,
400405
/* Assign a gref to this page */
401406
gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head);
402407
BUG_ON(gnt_list_entry->gref == -ENOSPC);
403-
if (!info->feature_persistent) {
408+
if (!info->bounce) {
404409
struct page *indirect_page;
405410

406411
/* Fetch a pre-allocated page to use for indirect grefs */
@@ -703,7 +708,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
703708
.grant_idx = 0,
704709
.segments = NULL,
705710
.rinfo = rinfo,
706-
.need_copy = rq_data_dir(req) && info->feature_persistent,
711+
.need_copy = rq_data_dir(req) && info->bounce,
707712
};
708713

709714
/*
@@ -981,11 +986,12 @@ static void xlvbd_flush(struct blkfront_info *info)
981986
{
982987
blk_queue_write_cache(info->rq, info->feature_flush ? true : false,
983988
info->feature_fua ? true : false);
984-
pr_info("blkfront: %s: %s %s %s %s %s\n",
989+
pr_info("blkfront: %s: %s %s %s %s %s %s %s\n",
985990
info->gd->disk_name, flush_info(info),
986991
"persistent grants:", info->feature_persistent ?
987992
"enabled;" : "disabled;", "indirect descriptors:",
988-
info->max_indirect_segments ? "enabled;" : "disabled;");
993+
info->max_indirect_segments ? "enabled;" : "disabled;",
994+
"bounce buffer:", info->bounce ? "enabled" : "disabled;");
989995
}
990996

991997
static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset)
@@ -1207,7 +1213,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo)
12071213
if (!list_empty(&rinfo->indirect_pages)) {
12081214
struct page *indirect_page, *n;
12091215

1210-
BUG_ON(info->feature_persistent);
1216+
BUG_ON(info->bounce);
12111217
list_for_each_entry_safe(indirect_page, n, &rinfo->indirect_pages, lru) {
12121218
list_del(&indirect_page->lru);
12131219
__free_page(indirect_page);
@@ -1224,7 +1230,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo)
12241230
NULL);
12251231
rinfo->persistent_gnts_c--;
12261232
}
1227-
if (info->feature_persistent)
1233+
if (info->bounce)
12281234
__free_page(persistent_gnt->page);
12291235
kfree(persistent_gnt);
12301236
}
@@ -1245,7 +1251,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo)
12451251
for (j = 0; j < segs; j++) {
12461252
persistent_gnt = rinfo->shadow[i].grants_used[j];
12471253
gnttab_end_foreign_access(persistent_gnt->gref, NULL);
1248-
if (info->feature_persistent)
1254+
if (info->bounce)
12491255
__free_page(persistent_gnt->page);
12501256
kfree(persistent_gnt);
12511257
}
@@ -1428,7 +1434,7 @@ static int blkif_completion(unsigned long *id,
14281434
data.s = s;
14291435
num_sg = s->num_sg;
14301436

1431-
if (bret->operation == BLKIF_OP_READ && info->feature_persistent) {
1437+
if (bret->operation == BLKIF_OP_READ && info->bounce) {
14321438
for_each_sg(s->sg, sg, num_sg, i) {
14331439
BUG_ON(sg->offset + sg->length > PAGE_SIZE);
14341440

@@ -1487,7 +1493,7 @@ static int blkif_completion(unsigned long *id,
14871493
* Add the used indirect page back to the list of
14881494
* available pages for indirect grefs.
14891495
*/
1490-
if (!info->feature_persistent) {
1496+
if (!info->bounce) {
14911497
indirect_page = s->indirect_grants[i]->page;
14921498
list_add(&indirect_page->lru, &rinfo->indirect_pages);
14931499
}
@@ -1764,6 +1770,10 @@ static int talk_to_blkback(struct xenbus_device *dev,
17641770
if (!info)
17651771
return -ENODEV;
17661772

1773+
/* Check if backend is trusted. */
1774+
info->bounce = !xen_blkif_trusted ||
1775+
!xenbus_read_unsigned(dev->nodename, "trusted", 1);
1776+
17671777
max_page_order = xenbus_read_unsigned(info->xbdev->otherend,
17681778
"max-ring-page-order", 0);
17691779
ring_page_order = min(xen_blkif_max_ring_order, max_page_order);
@@ -2173,17 +2183,18 @@ static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo)
21732183
if (err)
21742184
goto out_of_memory;
21752185

2176-
if (!info->feature_persistent && info->max_indirect_segments) {
2186+
if (!info->bounce && info->max_indirect_segments) {
21772187
/*
2178-
* We are using indirect descriptors but not persistent
2179-
* grants, we need to allocate a set of pages that can be
2188+
* We are using indirect descriptors but don't have a bounce
2189+
* buffer, we need to allocate a set of pages that can be
21802190
* used for mapping indirect grefs
21812191
*/
21822192
int num = INDIRECT_GREFS(grants) * BLK_RING_SIZE(info);
21832193

21842194
BUG_ON(!list_empty(&rinfo->indirect_pages));
21852195
for (i = 0; i < num; i++) {
2186-
struct page *indirect_page = alloc_page(GFP_KERNEL);
2196+
struct page *indirect_page = alloc_page(GFP_KERNEL |
2197+
__GFP_ZERO);
21872198
if (!indirect_page)
21882199
goto out_of_memory;
21892200
list_add(&indirect_page->lru, &rinfo->indirect_pages);
@@ -2276,6 +2287,8 @@ static void blkfront_gather_backend_features(struct blkfront_info *info)
22762287
info->feature_persistent =
22772288
!!xenbus_read_unsigned(info->xbdev->otherend,
22782289
"feature-persistent", 0);
2290+
if (info->feature_persistent)
2291+
info->bounce = true;
22792292

22802293
indirect_segments = xenbus_read_unsigned(info->xbdev->otherend,
22812294
"feature-max-indirect-segments", 0);
@@ -2547,6 +2560,13 @@ static void blkfront_delay_work(struct work_struct *work)
25472560
struct blkfront_info *info;
25482561
bool need_schedule_work = false;
25492562

2563+
/*
2564+
* Note that when using bounce buffers but not persistent grants
2565+
* there's no need to run blkfront_delay_work because grants are
2566+
* revoked in blkif_completion or else an error is reported and the
2567+
* connection is closed.
2568+
*/
2569+
25502570
mutex_lock(&blkfront_mutex);
25512571

25522572
list_for_each_entry(info, &info_list, info_list) {

drivers/net/xen-netfront.c

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ module_param_named(max_queues, xennet_max_queues, uint, 0644);
6666
MODULE_PARM_DESC(max_queues,
6767
"Maximum number of queues per virtual interface");
6868

69+
static bool __read_mostly xennet_trusted = true;
70+
module_param_named(trusted, xennet_trusted, bool, 0644);
71+
MODULE_PARM_DESC(trusted, "Is the backend trusted");
72+
6973
#define XENNET_TIMEOUT (5 * HZ)
7074

7175
static const struct ethtool_ops xennet_ethtool_ops;
@@ -173,6 +177,9 @@ struct netfront_info {
173177
/* Is device behaving sane? */
174178
bool broken;
175179

180+
/* Should skbs be bounced into a zeroed buffer? */
181+
bool bounce;
182+
176183
atomic_t rx_gso_checksum_fixup;
177184
};
178185

@@ -271,7 +278,8 @@ static struct sk_buff *xennet_alloc_one_rx_buffer(struct netfront_queue *queue)
271278
if (unlikely(!skb))
272279
return NULL;
273280

274-
page = page_pool_dev_alloc_pages(queue->page_pool);
281+
page = page_pool_alloc_pages(queue->page_pool,
282+
GFP_ATOMIC | __GFP_NOWARN | __GFP_ZERO);
275283
if (unlikely(!page)) {
276284
kfree_skb(skb);
277285
return NULL;
@@ -665,6 +673,33 @@ static int xennet_xdp_xmit(struct net_device *dev, int n,
665673
return nxmit;
666674
}
667675

676+
struct sk_buff *bounce_skb(const struct sk_buff *skb)
677+
{
678+
unsigned int headerlen = skb_headroom(skb);
679+
/* Align size to allocate full pages and avoid contiguous data leaks */
680+
unsigned int size = ALIGN(skb_end_offset(skb) + skb->data_len,
681+
XEN_PAGE_SIZE);
682+
struct sk_buff *n = alloc_skb(size, GFP_ATOMIC | __GFP_ZERO);
683+
684+
if (!n)
685+
return NULL;
686+
687+
if (!IS_ALIGNED((uintptr_t)n->head, XEN_PAGE_SIZE)) {
688+
WARN_ONCE(1, "misaligned skb allocated\n");
689+
kfree_skb(n);
690+
return NULL;
691+
}
692+
693+
/* Set the data pointer */
694+
skb_reserve(n, headerlen);
695+
/* Set the tail pointer and length */
696+
skb_put(n, skb->len);
697+
698+
BUG_ON(skb_copy_bits(skb, -headerlen, n->head, headerlen + skb->len));
699+
700+
skb_copy_header(n, skb);
701+
return n;
702+
}
668703

669704
#define MAX_XEN_SKB_FRAGS (65536 / XEN_PAGE_SIZE + 1)
670705

@@ -718,9 +753,13 @@ static netdev_tx_t xennet_start_xmit(struct sk_buff *skb, struct net_device *dev
718753

719754
/* The first req should be at least ETH_HLEN size or the packet will be
720755
* dropped by netback.
756+
*
757+
* If the backend is not trusted bounce all data to zeroed pages to
758+
* avoid exposing contiguous data on the granted page not belonging to
759+
* the skb.
721760
*/
722-
if (unlikely(PAGE_SIZE - offset < ETH_HLEN)) {
723-
nskb = skb_copy(skb, GFP_ATOMIC);
761+
if (np->bounce || unlikely(PAGE_SIZE - offset < ETH_HLEN)) {
762+
nskb = bounce_skb(skb);
724763
if (!nskb)
725764
goto drop;
726765
dev_consume_skb_any(skb);
@@ -1053,8 +1092,10 @@ static int xennet_get_responses(struct netfront_queue *queue,
10531092
}
10541093
}
10551094
rcu_read_unlock();
1056-
next:
1095+
10571096
__skb_queue_tail(list, skb);
1097+
1098+
next:
10581099
if (!(rx->flags & XEN_NETRXF_more_data))
10591100
break;
10601101

@@ -2214,6 +2255,10 @@ static int talk_to_netback(struct xenbus_device *dev,
22142255

22152256
info->netdev->irq = 0;
22162257

2258+
/* Check if backend is trusted. */
2259+
info->bounce = !xennet_trusted ||
2260+
!xenbus_read_unsigned(dev->nodename, "trusted", 1);
2261+
22172262
/* Check if backend supports multiple queues */
22182263
max_queues = xenbus_read_unsigned(info->xbdev->otherend,
22192264
"multi-queue-max-queues", 1);
@@ -2381,6 +2426,9 @@ static int xennet_connect(struct net_device *dev)
23812426
return err;
23822427
if (np->netback_has_xdp_headroom)
23832428
pr_info("backend supports XDP headroom\n");
2429+
if (np->bounce)
2430+
dev_info(&np->xbdev->dev,
2431+
"bouncing transmitted data to zeroed pages\n");
23842432

23852433
/* talk_to_netback() sets the correct number of queues */
23862434
num_queues = dev->real_num_tx_queues;

0 commit comments

Comments
 (0)