mirror of
https://github.com/xemu-project/xemu.git
synced 2024-12-05 10:16:50 +00:00
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1 iQEcBAABAgAGBQJfFu4hAAoJEO8Ells5jWIR10oH/1QlUjIdOY9/AgCi7yxof3iG F5ea/AJvYICTwleRSoUY8ZRtGlPw/FMJr/CBmSLuSGgGjAV86eHSih9dYNHUoFc/ jXNq5E/92xV4Ht55YF6AibIEEV5WSUNTF14XpqyL6UCmjZyAvoJwMwjPCDiTiqtY EjiLhDxHgUj2kKGlthVy5xUjDJ2XSH65NKrVIzdhCmahazA3m1L6ucP7ZBlGw7QJ XFxqf8cC3qwaYbPWDsGmQK8Q9KGB7g0Xgvoc8wWPpOpW0wGzRzMcAPzIl9HaMJkr oL+hJtMUxkN53ZR+RnnbmQqACaeu12T77RL0hljG3HQQDPQ1YtJ3G+QhkEaXlNg= =WAG7 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging # gpg: Signature made Tue 21 Jul 2020 14:31:13 BST # gpg: using RSA key EF04965B398D6211 # gpg: Good signature from "Jason Wang (Jason Wang on RedHat) <jasowang@redhat.com>" [marginal] # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 215D 46F4 8246 689E C77F 3562 EF04 965B 398D 6211 * remotes/jasowang/tags/net-pull-request: hw/net/xgmac: Fix buffer overflow in xgmac_enet_send() hw/net: Added plen fix for IPv6 Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
5252220dbf
@ -626,6 +626,7 @@ bool net_tx_pkt_send(struct NetTxPkt *pkt, NetClientState *nc)
|
||||
|
||||
if (pkt->has_virt_hdr ||
|
||||
pkt->virt_hdr.gso_type == VIRTIO_NET_HDR_GSO_NONE) {
|
||||
net_tx_pkt_fix_ip6_payload_len(pkt);
|
||||
net_tx_pkt_sendv(pkt, nc, pkt->vec,
|
||||
pkt->payload_frags + NET_TX_PKT_PL_START_FRAG);
|
||||
return true;
|
||||
@ -644,3 +645,25 @@ bool net_tx_pkt_send_loopback(struct NetTxPkt *pkt, NetClientState *nc)
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void net_tx_pkt_fix_ip6_payload_len(struct NetTxPkt *pkt)
|
||||
{
|
||||
struct iovec *l2 = &pkt->vec[NET_TX_PKT_L2HDR_FRAG];
|
||||
if (eth_get_l3_proto(l2, 1, l2->iov_len) == ETH_P_IPV6) {
|
||||
struct ip6_header *ip6 = (struct ip6_header *) pkt->l3_hdr;
|
||||
/*
|
||||
* TODO: if qemu would support >64K packets - add jumbo option check
|
||||
* something like that:
|
||||
* 'if (ip6->ip6_plen == 0 && !has_jumbo_option(ip6)) {'
|
||||
*/
|
||||
if (ip6->ip6_plen == 0) {
|
||||
if (pkt->payload_len <= ETH_MAX_IP_DGRAM_LEN) {
|
||||
ip6->ip6_plen = htons(pkt->payload_len);
|
||||
}
|
||||
/*
|
||||
* TODO: if qemu would support >64K packets
|
||||
* add jumbo option for packets greater then 65,535 bytes
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -187,4 +187,18 @@ bool net_tx_pkt_parse(struct NetTxPkt *pkt);
|
||||
*/
|
||||
bool net_tx_pkt_has_fragments(struct NetTxPkt *pkt);
|
||||
|
||||
/**
|
||||
* Fix IPv6 'plen' field.
|
||||
* If ipv6 payload length field is 0 - then there should be Hop-by-Hop
|
||||
* option for packets greater than 65,535.
|
||||
* For packets with a payload less than 65,535: fix 'plen' field.
|
||||
* For backends with vheader, we need just one packet with proper
|
||||
* payload size. For now, qemu drops every packet with size greater 64K
|
||||
* (see net_tx_pkt_send()) so, there is no reason to add jumbo option to ip6
|
||||
* hop-by-hop extension if it's missed
|
||||
*
|
||||
* @pkt packet
|
||||
*/
|
||||
void net_tx_pkt_fix_ip6_payload_len(struct NetTxPkt *pkt);
|
||||
|
||||
#endif
|
||||
|
@ -220,21 +220,31 @@ static void xgmac_enet_send(XgmacState *s)
|
||||
}
|
||||
len = (bd.buffer1_size & 0xfff) + (bd.buffer2_size & 0xfff);
|
||||
|
||||
/*
|
||||
* FIXME: these cases of malformed tx descriptors (bad sizes)
|
||||
* should probably be reported back to the guest somehow
|
||||
* rather than simply silently stopping processing, but we
|
||||
* don't know what the hardware does in this situation.
|
||||
* This will only happen for buggy guests anyway.
|
||||
*/
|
||||
if ((bd.buffer1_size & 0xfff) > 2048) {
|
||||
DEBUGF_BRK("qemu:%s:ERROR...ERROR...ERROR... -- "
|
||||
"xgmac buffer 1 len on send > 2048 (0x%x)\n",
|
||||
__func__, bd.buffer1_size & 0xfff);
|
||||
break;
|
||||
}
|
||||
if ((bd.buffer2_size & 0xfff) != 0) {
|
||||
DEBUGF_BRK("qemu:%s:ERROR...ERROR...ERROR... -- "
|
||||
"xgmac buffer 2 len on send != 0 (0x%x)\n",
|
||||
__func__, bd.buffer2_size & 0xfff);
|
||||
break;
|
||||
}
|
||||
if (len >= sizeof(frame)) {
|
||||
if (frame_size + len >= sizeof(frame)) {
|
||||
DEBUGF_BRK("qemu:%s: buffer overflow %d read into %zu "
|
||||
"buffer\n" , __func__, len, sizeof(frame));
|
||||
"buffer\n" , __func__, frame_size + len, sizeof(frame));
|
||||
DEBUGF_BRK("qemu:%s: buffer1.size=%d; buffer2.size=%d\n",
|
||||
__func__, bd.buffer1_size, bd.buffer2_size);
|
||||
break;
|
||||
}
|
||||
|
||||
cpu_physical_memory_read(bd.buffer1_addr, ptr, len);
|
||||
|
@ -186,6 +186,7 @@ struct tcp_hdr {
|
||||
|
||||
#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
|
||||
#define ip6_ecn_acc ip6_ctlun.ip6_un3.ip6_un3_ecn
|
||||
#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
|
||||
|
||||
#define PKT_GET_ETH_HDR(p) \
|
||||
((struct eth_header *)(p))
|
||||
|
Loading…
Reference in New Issue
Block a user