| From 1201d308519f1e915866d7583d5136d03cc1d384 Mon Sep 17 00:00:00 2001 |
| From: Samuel Thibault <samuel.thibault@ens-lyon.org> |
| Date: Fri, 25 Aug 2017 01:35:53 +0200 |
| Subject: [PATCH] slirp: fix clearing ifq_so from pending packets |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| The if_fastq and if_batchq contain not only packets, but queues of packets |
| for the same socket. When sofree frees a socket, it thus has to clear ifq_so |
| from all the packets from the queues, not only the first. |
| |
| Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> |
| Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> |
| Cc: qemu-stable@nongnu.org |
| Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
| |
| Upstream-Status: Backport |
| [https://git.qemu.org/?p=qemu.git;a=commit;h=1201d308519f1e915866d7583d5136d03cc1d384] |
| |
| CVE: CVE-2017-13711 |
| |
| Signed-off-by: Yi Zhao <yi.zhao@windriver.com> |
| --- |
| slirp/socket.c | 39 +++++++++++++++++++++++---------------- |
| 1 file changed, 23 insertions(+), 16 deletions(-) |
| |
| diff --git a/slirp/socket.c b/slirp/socket.c |
| index ecec029..cb7b5b6 100644 |
| --- a/slirp/socket.c |
| +++ b/slirp/socket.c |
| @@ -60,29 +60,36 @@ socreate(Slirp *slirp) |
| } |
| |
| /* |
| + * Remove references to so from the given message queue. |
| + */ |
| +static void |
| +soqfree(struct socket *so, struct quehead *qh) |
| +{ |
| + struct mbuf *ifq; |
| + |
| + for (ifq = (struct mbuf *) qh->qh_link; |
| + (struct quehead *) ifq != qh; |
| + ifq = ifq->ifq_next) { |
| + if (ifq->ifq_so == so) { |
| + struct mbuf *ifm; |
| + ifq->ifq_so = NULL; |
| + for (ifm = ifq->ifs_next; ifm != ifq; ifm = ifm->ifs_next) { |
| + ifm->ifq_so = NULL; |
| + } |
| + } |
| + } |
| +} |
| + |
| +/* |
| * remque and free a socket, clobber cache |
| */ |
| void |
| sofree(struct socket *so) |
| { |
| Slirp *slirp = so->slirp; |
| - struct mbuf *ifm; |
| |
| - for (ifm = (struct mbuf *) slirp->if_fastq.qh_link; |
| - (struct quehead *) ifm != &slirp->if_fastq; |
| - ifm = ifm->ifq_next) { |
| - if (ifm->ifq_so == so) { |
| - ifm->ifq_so = NULL; |
| - } |
| - } |
| - |
| - for (ifm = (struct mbuf *) slirp->if_batchq.qh_link; |
| - (struct quehead *) ifm != &slirp->if_batchq; |
| - ifm = ifm->ifq_next) { |
| - if (ifm->ifq_so == so) { |
| - ifm->ifq_so = NULL; |
| - } |
| - } |
| + soqfree(so, &slirp->if_fastq); |
| + soqfree(so, &slirp->if_batchq); |
| |
| if (so->so_emu==EMU_RSH && so->extra) { |
| sofree(so->extra); |
| -- |
| 2.7.4 |
| |