Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:Update
qemu-linux-user
0338-slirp-don-t-manipulate-so_rcv-in-tc.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0338-slirp-don-t-manipulate-so_rcv-in-tc.patch of Package qemu-linux-user
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com> Date: Fri, 3 May 2019 13:34:45 +0200 Subject: slirp: don't manipulate so_rcv in tcp_emu() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For some reason, EMU_IDENT is not like other "emulated" protocols and tries to reconstitute the original buffer, if it came in multiple packets. Unfortunately, it does so wrongly, as it doesn't respect the sbuf circular buffer appending rules, nor does it maintain some of the invariants (rptr is incremented without bounds, etc): this leads to further memory corruption revealed by ASAN or various malloc errors. Furthermore, the so_rcv buffer is regularly flushed, so there is no guarantee that buffer reconstruction will do what is expected. Instead, do what the function comment says: "XXX Assumes the whole command came in one packet", and don't touch so_rcv. Related to: https://bugzilla.redhat.com/show_bug.cgi?id=1664205 Cc: Prasad J Pandit <pjp@fedoraproject.org> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> --- slirp/tcp_subr.c | 59 +++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c index c82c8937deb948d9ce1e1acd85d9..a07f6258655d72257e67a1c228b2 100644 --- a/slirp/tcp_subr.c +++ b/slirp/tcp_subr.c @@ -639,46 +639,39 @@ tcp_emu(struct socket *so, struct mbuf *m) struct socket *tmpso; struct sockaddr_in addr; socklen_t addrlen = sizeof(struct sockaddr_in); - struct sbuf *so_rcv = &so->so_rcv; + char *eol = g_strstr_len(m->m_data, m->m_len, "\r\n"); - if (m->m_len > so_rcv->sb_datalen - (so_rcv->sb_wptr - so_rcv->sb_data)) { + if (!eol) { return 1; } - memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); - so_rcv->sb_wptr += m->m_len; - so_rcv->sb_rptr += m->m_len; - m_inc(m, m->m_len + 1); - m->m_data[m->m_len] = 0; /* NULL terminate */ - if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) { - if (sscanf(so_rcv->sb_data, "%u%*[ ,]%u", &n1, &n2) == 2) { - HTONS(n1); - HTONS(n2); - /* n2 is the one on our host */ - for (tmpso = slirp->tcb.so_next; - tmpso != &slirp->tcb; - tmpso = tmpso->so_next) { - if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr && - tmpso->so_lport == n2 && - tmpso->so_faddr.s_addr == so->so_faddr.s_addr && - tmpso->so_fport == n1) { - if (getsockname(tmpso->s, - (struct sockaddr *)&addr, &addrlen) == 0) - n2 = addr.sin_port; - break; - } + *eol = '\0'; + if (sscanf(m->m_data, "%u%*[ ,]%u", &n1, &n2) == 2) { + HTONS(n1); + HTONS(n2); + /* n2 is the one on our host */ + for (tmpso = slirp->tcb.so_next; tmpso != &slirp->tcb; + tmpso = tmpso->so_next) { + if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr && + tmpso->so_lport == n2 && + tmpso->so_faddr.s_addr == so->so_faddr.s_addr && + tmpso->so_fport == n1) { + if (getsockname(tmpso->s, (struct sockaddr *)&addr, + &addrlen) == 0) + n2 = addr.sin_port; + break; } - NTOHS(n1); - NTOHS(n2); - so_rcv->sb_cc = snprintf(so_rcv->sb_data, - so_rcv->sb_datalen, - "%d,%d\r\n", n1, n2); - so_rcv->sb_rptr = so_rcv->sb_data; - so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; } + NTOHS(n1); + NTOHS(n2); + m_inc(m, snprintf(NULL, 0, "%d,%d\r\n", n1, n2) + 1); + m->m_len = snprintf(m->m_data, M_ROOM(m), "%d,%d\r\n", n1, n2); + assert(m->m_len < M_ROOM(m)); + } else { + *eol = '\r'; } - m_free(m); - return 0; + + return 1; } case EMU_FTP: /* ftp */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor