Skip to content

Commit

Permalink
xen/netfront: force data bouncing when backend is untrusted
Browse files Browse the repository at this point in the history
commit 4491001 upstream.

Bounce all data on the skbs to be transmitted into zeroed pages if the
backend is untrusted. This avoids leaking data present in the pages
shared with the backend but not part of the skb fragments.  This
requires introducing a new helper in order to allocate skbs with a
size multiple of XEN_PAGE_SIZE so we don't leak contiguous data on the
granted pages.

Reporting whether the backend is to be trusted can be done using a
module parameter, or from the xenstore frontend path as set by the
toolstack when adding the device.

This is CVE-2022-33741, part of XSA-403.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
royger authored and gregkh committed Jul 7, 2022
1 parent 728d68b commit 4923217
Showing 1 changed file with 47 additions and 2 deletions.
49 changes: 47 additions & 2 deletions drivers/net/xen-netfront.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ module_param_named(max_queues, xennet_max_queues, uint, 0644);
MODULE_PARM_DESC(max_queues,
"Maximum number of queues per virtual interface");

static bool __read_mostly xennet_trusted = true;
module_param_named(trusted, xennet_trusted, bool, 0644);
MODULE_PARM_DESC(trusted, "Is the backend trusted");

#define XENNET_TIMEOUT (5 * HZ)

static const struct ethtool_ops xennet_ethtool_ops;
Expand Down Expand Up @@ -175,6 +179,9 @@ struct netfront_info {
/* Is device behaving sane? */
bool broken;

/* Should skbs be bounced into a zeroed buffer? */
bool bounce;

atomic_t rx_gso_checksum_fixup;
};

Expand Down Expand Up @@ -670,6 +677,33 @@ static int xennet_xdp_xmit(struct net_device *dev, int n,
return n - drops;
}

struct sk_buff *bounce_skb(const struct sk_buff *skb)
{
unsigned int headerlen = skb_headroom(skb);
/* Align size to allocate full pages and avoid contiguous data leaks */
unsigned int size = ALIGN(skb_end_offset(skb) + skb->data_len,
XEN_PAGE_SIZE);
struct sk_buff *n = alloc_skb(size, GFP_ATOMIC | __GFP_ZERO);

if (!n)
return NULL;

if (!IS_ALIGNED((uintptr_t)n->head, XEN_PAGE_SIZE)) {
WARN_ONCE(1, "misaligned skb allocated\n");
kfree_skb(n);
return NULL;
}

/* Set the data pointer */
skb_reserve(n, headerlen);
/* Set the tail pointer and length */
skb_put(n, skb->len);

BUG_ON(skb_copy_bits(skb, -headerlen, n->head, headerlen + skb->len));

skb_copy_header(n, skb);
return n;
}

#define MAX_XEN_SKB_FRAGS (65536 / XEN_PAGE_SIZE + 1)

Expand Down Expand Up @@ -723,9 +757,13 @@ static netdev_tx_t xennet_start_xmit(struct sk_buff *skb, struct net_device *dev

/* The first req should be at least ETH_HLEN size or the packet will be
* dropped by netback.
*
* If the backend is not trusted bounce all data to zeroed pages to
* avoid exposing contiguous data on the granted page not belonging to
* the skb.
*/
if (unlikely(PAGE_SIZE - offset < ETH_HLEN)) {
nskb = skb_copy(skb, GFP_ATOMIC);
if (np->bounce || unlikely(PAGE_SIZE - offset < ETH_HLEN)) {
nskb = bounce_skb(skb);
if (!nskb)
goto drop;
dev_consume_skb_any(skb);
Expand Down Expand Up @@ -2249,6 +2287,10 @@ static int talk_to_netback(struct xenbus_device *dev,

info->netdev->irq = 0;

/* Check if backend is trusted. */
info->bounce = !xennet_trusted ||
!xenbus_read_unsigned(dev->nodename, "trusted", 1);

/* Check if backend supports multiple queues */
max_queues = xenbus_read_unsigned(info->xbdev->otherend,
"multi-queue-max-queues", 1);
Expand Down Expand Up @@ -2415,6 +2457,9 @@ static int xennet_connect(struct net_device *dev)
return err;
if (np->netback_has_xdp_headroom)
pr_info("backend supports XDP headroom\n");
if (np->bounce)
dev_info(&np->xbdev->dev,
"bouncing transmitted data to zeroed pages\n");

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

0 comments on commit 4923217

Please sign in to comment.