Throw exception for invalid packets at packet streams

Some application code is dereferencing the pointer returned by
'packet_content' at packet streams without checking that it is valid.
Throw an exception rather than return a null pointer, except for
zero-length packets, which have somewhat implicit invalid content and
that we believe to be properly handled in all current cases.

The client-side of a packet stream cannot take corrective action if the
server-side is sending packets with invalid content, but the servers
that provide packet streams should catch this exception to detect
misbehaving clients.

Ref #3059
This commit is contained in:
Emery Hemingway
2018-11-25 11:58:58 +01:00
committed by Christian Helmuth
parent e5d1d26535
commit a2bdcc68c2
20 changed files with 100 additions and 77 deletions

View File

@ -82,7 +82,7 @@ bool Session_component::_send()
if (!_tx.sink()->packet_avail()) { return false; }
Packet_descriptor packet = _tx.sink()->get_packet();
if (!packet.size()) {
if (!packet.size() || !_tx.sink()->packet_valid(packet)) {
warning("invalid tx packet");
return true;
}

View File

@ -497,7 +497,8 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
_p_in_flight++;
if (!_device || !_device->udev ||
_device->udev->state == USB_STATE_NOTATTACHED) {
_device->udev->state == USB_STATE_NOTATTACHED ||
!_sink->packet_valid(p)) {
_ack_packet(p);
continue;
}

View File

@ -82,7 +82,7 @@ bool Session_component::_send()
if (!_tx.sink()->packet_avail()) { return false; }
Packet_descriptor packet = _tx.sink()->get_packet();
if (!packet.size()) {
if (!packet.size() || !_tx.sink()->packet_valid(packet)) {
warning("invalid tx packet");
return true;
}

View File

@ -74,8 +74,9 @@ class Nic_client
count++ < MAX_PACKETS)
{
Nic::Packet_descriptor p = _nic.rx()->get_packet();
net_driver_rx(_nic.rx()->packet_content(p), p.size());
try { net_driver_rx(_nic.rx()->packet_content(p), p.size()); }
catch (Genode::Packet_descriptor::Invalid_packet) {
Genode::error("received invalid Nic packet"); }
_nic.rx()->acknowledge_packet(p);
}

View File

@ -131,7 +131,8 @@ class Usb_nic::Session_component : public Nic::Session_component
}
/* copy packet to current data pos */
Genode::memcpy(work_skb.data, _tx.sink()->packet_content(packet), packet.size());
try { Genode::memcpy(work_skb.data, _tx.sink()->packet_content(packet), packet.size()); }
catch (Genode::Packet_descriptor::Invalid_packet) { }
/* call fixup on dummy SKB */
_device->tx_fixup(&work_skb);
/* advance to next slot */
@ -155,7 +156,7 @@ class Usb_nic::Session_component : public Nic::Session_component
return false;
Genode::Packet_descriptor packet = _tx.sink()->get_packet();
if (!packet.size()) {
if (!packet.size() || !_tx.sink()->packet_valid(packet)) {
Genode::warning("Invalid tx packet");
return true;
}

View File

@ -482,7 +482,7 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
_p_in_flight++;
if (!_device || !_device->udev) {
if (!_device || !_device->udev || !_sink->packet_valid(p)) {
_ack_packet(p);
continue;
}

View File

@ -138,7 +138,7 @@ class Wifi_session_component : public Nic::Session_component
if (!_tx.sink()->packet_avail()) { return false; }
Packet_descriptor packet = _tx.sink()->get_packet();
if (!packet.size()) {
if (!packet.size() || !_tx.sink()->packet_valid(packet)) {
warning("invalid tx packet");
return true;
}