Andrew Geissler | 09209ee | 2020-12-13 08:44:15 -0600 | [diff] [blame] | 1 | From 2e1dcbc0c2af64fcb17009eaf2ceedd81be2b27f Mon Sep 17 00:00:00 2001 |
| 2 | From: Prasad J Pandit <pjp@fedoraproject.org> |
| 3 | Date: Thu, 26 Nov 2020 19:27:06 +0530 |
| 4 | Subject: [PATCH] slirp: check pkt_len before reading protocol header |
| 5 | MIME-Version: 1.0 |
| 6 | Content-Type: text/plain; charset=utf8 |
| 7 | Content-Transfer-Encoding: 8bit |
| 8 | |
| 9 | While processing ARP/NCSI packets in 'arp_input' or 'ncsi_input' |
| 10 | routines, ensure that pkt_len is large enough to accommodate the |
| 11 | respective protocol headers, lest it should do an OOB access. |
| 12 | Add check to avoid it. |
| 13 | |
| 14 | CVE-2020-29129 CVE-2020-29130 |
| 15 | QEMU: slirp: out-of-bounds access while processing ARP/NCSI packets |
| 16 | -> https://www.openwall.com/lists/oss-security/2020/11/27/1 |
| 17 | |
| 18 | Reported-by: Qiuhao Li <Qiuhao.Li@outlook.com> |
| 19 | Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> |
| 20 | Message-Id: <20201126135706.273950-1-ppandit@redhat.com> |
| 21 | Reviewed-by: Marc-Andrà Lureau <marcandre.lureau@redhat.com> |
| 22 | |
| 23 | Upstream-Status: Backport |
| 24 | CVE: CVE-2020-29129 CVE-2020-29130 |
| 25 | [https://git.qemu.org/?p=libslirp.git;a=commit;h=2e1dcbc0c2af64fcb17009eaf2ceedd81be2b27f] |
| 26 | Signed-off-by: Li Wang <li.wang@windriver.com> |
| 27 | --- |
| 28 | slirp/src/ncsi.c | 4 ++++ |
| 29 | slirp/src/slirp.c | 4 ++++ |
| 30 | 2 files changed, 8 insertions(+) |
| 31 | |
| 32 | diff --git a/slirp/src/ncsi.c b/slirp/src/ncsi.c |
| 33 | index 3c1dfef..75dcc08 100644 |
| 34 | --- a/slirp/src/ncsi.c |
| 35 | +++ b/slirp/src/ncsi.c |
| 36 | @@ -148,6 +148,10 @@ void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) |
| 37 | uint32_t checksum; |
| 38 | uint32_t *pchecksum; |
| 39 | |
| 40 | + if (pkt_len < ETH_HLEN + sizeof(struct ncsi_pkt_hdr)) { |
| 41 | + return; /* packet too short */ |
| 42 | + } |
| 43 | + |
| 44 | memset(ncsi_reply, 0, sizeof(ncsi_reply)); |
| 45 | |
| 46 | memset(reh->h_dest, 0xff, ETH_ALEN); |
| 47 | diff --git a/slirp/src/slirp.c b/slirp/src/slirp.c |
| 48 | index dba7c98..9be58e2 100644 |
| 49 | --- a/slirp/src/slirp.c |
| 50 | +++ b/slirp/src/slirp.c |
| 51 | @@ -756,6 +756,10 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) |
| 52 | return; |
| 53 | } |
| 54 | |
| 55 | + if (pkt_len < ETH_HLEN + sizeof(struct slirp_arphdr)) { |
| 56 | + return; /* packet too short */ |
| 57 | + } |
| 58 | + |
| 59 | ar_op = ntohs(ah->ar_op); |
| 60 | switch (ar_op) { |
| 61 | case ARPOP_REQUEST: |
| 62 | -- |
| 63 | 2.17.1 |
| 64 | |