summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Mooney <pmooney@pfmooney.com>2019-02-19 22:05:03 +0000
committerPatrick Mooney <pmooney@pfmooney.com>2019-02-21 21:59:53 +0000
commit4522981520131b068fafcb587c7e3542cad79117 (patch)
treeb2868cf0cf44b23845c1b0b1fa72e3dcba61b7c9
parent15c5e8a21e5a254e3ccfda29deff00097f655289 (diff)
downloadillumos-joyent-4522981520131b068fafcb587c7e3542cad79117.tar.gz
OS-7591 viona should be strict about cksum offsets
Reviewed by: Ryan Zezeski <rpz@joyent.com> Reviewed by: Robert Mustacchi <rm@joyent.com> Approved by: Robert Mustacchi <rm@joyent.com>
-rw-r--r--usr/src/uts/i86pc/io/viona/viona.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/usr/src/uts/i86pc/io/viona/viona.c b/usr/src/uts/i86pc/io/viona/viona.c
index 5fd5ddb5ea..4ae0f7317f 100644
--- a/usr/src/uts/i86pc/io/viona/viona.c
+++ b/usr/src/uts/i86pc/io/viona/viona.c
@@ -2532,9 +2532,18 @@ viona_tx_csum(viona_vring_t *ring, const struct virtio_net_hdr *hdr,
ipha_t *ipha = NULL;
uint8_t ipproto = IPPROTO_NONE; /* NONE is not exactly right, but ok */
uint16_t flags = 0;
+ const uint_t csum_start = hdr->vrh_csum_start;
+ const uint_t csum_stuff = hdr->vrh_csum_offset + csum_start;
- if (MBLKL(mp) < sizeof (*eth)) {
- /* Buffers shorter than an ethernet header are hopeless */
+ /*
+ * Validate that the checksum offsets provided by the guest are within
+ * the bounds of the packet. Additionally, ensure that the checksum
+ * contents field is within the headers mblk copied by viona_tx().
+ */
+ if (csum_start >= len || csum_start < eth_len || csum_stuff >= len ||
+ (csum_stuff + sizeof (uint16_t)) > MBLKL(mp)) {
+ VIONA_PROBE2(fail_hcksum, viona_link_t *, link, mblk_t *, mp);
+ VIONA_RING_STAT_INCR(ring, fail_hcksum);
return (B_FALSE);
}
@@ -2634,17 +2643,13 @@ viona_tx_csum(viona_vring_t *ring, const struct virtio_net_hdr *hdr,
*/
if ((link->l_cap_csum & HCKSUM_INET_PARTIAL) != 0 &&
(ipproto == IPPROTO_TCP || ipproto == IPPROTO_UDP)) {
- uint_t start, stuff, end;
-
/*
* MAC expects these offsets to be relative to the
* start of the L3 header rather than the L2 frame.
*/
- start = hdr->vrh_csum_start - eth_len;
- stuff = start + hdr->vrh_csum_offset;
- end = len - eth_len;
flags |= HCK_PARTIALCKSUM;
- mac_hcksum_set(mp, start, stuff, end, 0, flags);
+ mac_hcksum_set(mp, csum_start - eth_len, csum_stuff - eth_len,
+ len - eth_len, 0, flags);
return (B_TRUE);
}