[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 2/4] slirp: avoid use-after-free in slirp_pollfds_pol
From: |
Samuel Thibault |
Subject: |
[Qemu-devel] [PULL 2/4] slirp: avoid use-after-free in slirp_pollfds_poll() if soread() returns an error |
Date: |
Thu, 7 Apr 2016 13:04:11 +0200 |
From: Steven Luo <address@hidden>
Samuel Thibault pointed out that it's possible that slirp_pollfds_poll()
will try to use a socket even after soread() returns an error, resulting
in an use-after-free if the socket was removed while handling the error.
Avoid this by refusing to continue to work with the socket in this case.
Signed-off-by: Steven Luo <address@hidden>
Signed-off-by: Samuel Thibault <address@hidden>
---
slirp/slirp.c | 12 +++++++++++-
slirp/socket.c | 17 +++++++++++------
slirp/socket.h | 2 +-
3 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/slirp/slirp.c b/slirp/slirp.c
index fef526c..9f4bea3 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -534,7 +534,12 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
* test for G_IO_IN below if this succeeds
*/
if (revents & G_IO_PRI) {
- sorecvoob(so);
+ ret = sorecvoob(so);
+ if (ret < 0) {
+ /* Socket error might have resulted in the socket being
+ * removed, do not try to do anything more with it. */
+ continue;
+ }
}
/*
* Check sockets for reading
@@ -553,6 +558,11 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
if (ret > 0) {
tcp_output(sototcpcb(so));
}
+ if (ret < 0) {
+ /* Socket error might have resulted in the socket being
+ * removed, do not try to do anything more with it. */
+ continue;
+ }
}
/*
diff --git a/slirp/socket.c b/slirp/socket.c
index b836c42..7f022a6 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -260,10 +260,11 @@ err:
* so when OOB data arrives, we soread() it and everything
* in the send buffer is sent as urgent data
*/
-void
+int
sorecvoob(struct socket *so)
{
struct tcpcb *tp = sototcpcb(so);
+ int ret;
DEBUG_CALL("sorecvoob");
DEBUG_ARG("so = %p", so);
@@ -276,11 +277,15 @@ sorecvoob(struct socket *so)
* urgent data, or the read() doesn't return all the
* urgent data.
*/
- soread(so);
- tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
- tp->t_force = 1;
- tcp_output(tp);
- tp->t_force = 0;
+ ret = soread(so);
+ if (ret > 0) {
+ tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
+ tp->t_force = 1;
+ tcp_output(tp);
+ tp->t_force = 0;
+ }
+
+ return ret;
}
/*
diff --git a/slirp/socket.h b/slirp/socket.h
index e9c9b05..7dca506 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -127,7 +127,7 @@ struct socket *solookup(struct socket **, struct socket *,
struct socket *socreate(Slirp *);
void sofree(struct socket *);
int soread(struct socket *);
-void sorecvoob(struct socket *);
+int sorecvoob(struct socket *);
int sosendoob(struct socket *);
int sowrite(struct socket *);
void sorecvfrom(struct socket *);
--
2.8.0.rc3
- [Qemu-devel] [PULL 4/4] slirp: handle deferred ECONNREFUSED on non-blocking TCP sockets, (continued)
- [Qemu-devel] [PULL 4/4] slirp: handle deferred ECONNREFUSED on non-blocking TCP sockets, Samuel Thibault, 2016/04/07
- [Qemu-devel] [PULL 1/4] slirp: don't crash when tcp_sockclosed() is called with a NULL tp, Samuel Thibault, 2016/04/07
- [Qemu-devel] [PULL 2/4] slirp: avoid use-after-free in slirp_pollfds_poll() if soread() returns an error, Samuel Thibault, 2016/04/07
- [Qemu-devel] [PULL 3/4] slirp: Propagate host TCP RST to the guest., Samuel Thibault, 2016/04/07
- Re: [Qemu-devel] [PULL 0/4] slirp: deliver received TCP RSTs to the guest, Peter Maydell, 2016/04/07
- [Qemu-devel] [PULL 0/4] slirp: deliver received TCP RSTs to the guest, Samuel Thibault, 2016/04/07