diff --git a/core/hw/bba/bba.cpp b/core/hw/bba/bba.cpp index 2b1b49d4a..eb5556e09 100644 --- a/core/hw/bba/bba.cpp +++ b/core/hw/bba/bba.cpp @@ -49,6 +49,7 @@ static u8 GAPS_ram[GAPSPCI_RAM_SIZE]; static u8 GAPS_regs[GAPSPCI_REGS_SIZE]; static u32 dmaOffset; static bool interruptPending; +static constexpr u32 MAX_ETH_FRAME_SIZE = 1514; static void setInterrupt() { @@ -215,6 +216,8 @@ ssize_t qemu_send_packet(RTL8139State *s, const uint8_t *buf, int size) int bba_recv_frame(const u8 *data, u32 len) { + if (len < 6 || len > MAX_ETH_FRAME_SIZE) + return 0; if (!rtl8139_can_receive(rtl8139device)) return 0; rtl8139_receive(rtl8139device, data, len); diff --git a/core/network/dcnet.cpp b/core/network/dcnet.cpp index 85ba8983d..669af7320 100644 --- a/core/network/dcnet.cpp +++ b/core/network/dcnet.cpp @@ -42,6 +42,7 @@ namespace net::modbba { static TsQueue toModem; +static constexpr size_t MAX_ETH_FRAME_SIZE = 1514; class DCNetService : public Service { @@ -280,6 +281,8 @@ private: iterator i = begin; uint16_t len = (uint8_t)*i++; len |= uint8_t(*i++) << 8; + if (len > MAX_ETH_FRAME_SIZE) + return std::make_pair(begin + 2, true); len += 2; if (end - begin < len) return std::make_pair(begin, false); @@ -299,6 +302,14 @@ private: socket.close(ignored); return; } + uint16_t frameLen = recvBuffer[0] | recvBuffer[1] << 8; + if (frameLen > MAX_ETH_FRAME_SIZE || len != (size_t)frameLen + 2) + { + ERROR_LOG(NETWORK, "Invalid Ethernet frame size: %d", frameLen); + std::error_code ignored; + socket.close(ignored); + return; + } /* verify(len - 2 == *(u16 *)&recvBuffer[0]); printf("In frame: dest %02x:%02x:%02x:%02x:%02x:%02x "