| From 2e1dcbc0c2af64fcb17009eaf2ceedd81be2b27f Mon Sep 17 00:00:00 2001 |
| From: Prasad J Pandit <pjp@fedoraproject.org> |
| Date: Thu, 26 Nov 2020 19:27:06 +0530 |
| Subject: [PATCH] slirp: check pkt_len before reading protocol header |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=utf8 |
| Content-Transfer-Encoding: 8bit |
| |
| While processing ARP/NCSI packets in 'arp_input' or 'ncsi_input' |
| routines, ensure that pkt_len is large enough to accommodate the |
| respective protocol headers, lest it should do an OOB access. |
| Add check to avoid it. |
| |
| CVE-2020-29129 CVE-2020-29130 |
| QEMU: slirp: out-of-bounds access while processing ARP/NCSI packets |
| -> https://www.openwall.com/lists/oss-security/2020/11/27/1 |
| |
| Reported-by: Qiuhao Li <Qiuhao.Li@outlook.com> |
| Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> |
| Message-Id: <20201126135706.273950-1-ppandit@redhat.com> |
| Reviewed-by: Marc-Andrà Lureau <marcandre.lureau@redhat.com> |
| |
| Upstream-Status: Backport |
| CVE: CVE-2020-29129 CVE-2020-29130 |
| [https://git.qemu.org/?p=libslirp.git;a=commit;h=2e1dcbc0c2af64fcb17009eaf2ceedd81be2b27f] |
| Signed-off-by: Li Wang <li.wang@windriver.com> |
| --- |
| slirp/src/ncsi.c | 4 ++++ |
| slirp/src/slirp.c | 4 ++++ |
| 2 files changed, 8 insertions(+) |
| |
| diff --git a/slirp/src/ncsi.c b/slirp/src/ncsi.c |
| index 3c1dfef..75dcc08 100644 |
| --- a/slirp/src/ncsi.c |
| +++ b/slirp/src/ncsi.c |
| @@ -148,6 +148,10 @@ void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) |
| uint32_t checksum; |
| uint32_t *pchecksum; |
| |
| + if (pkt_len < ETH_HLEN + sizeof(struct ncsi_pkt_hdr)) { |
| + return; /* packet too short */ |
| + } |
| + |
| memset(ncsi_reply, 0, sizeof(ncsi_reply)); |
| |
| memset(reh->h_dest, 0xff, ETH_ALEN); |
| diff --git a/slirp/src/slirp.c b/slirp/src/slirp.c |
| index dba7c98..9be58e2 100644 |
| --- a/slirp/src/slirp.c |
| +++ b/slirp/src/slirp.c |
| @@ -756,6 +756,10 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) |
| return; |
| } |
| |
| + if (pkt_len < ETH_HLEN + sizeof(struct slirp_arphdr)) { |
| + return; /* packet too short */ |
| + } |
| + |
| ar_op = ntohs(ah->ar_op); |
| switch (ar_op) { |
| case ARPOP_REQUEST: |
| -- |
| 2.17.1 |
| |