diff options
author | Alex Crichton <alex@alexcrichton.com> | 2016-11-10 08:00:22 -0800 |
---|---|---|
committer | Patrick Steinhardt <ps@pks.im> | 2016-11-11 11:22:15 +0100 |
commit | 5ca75fd52c36f63fe9b1218e79953411d4435a9d (patch) | |
tree | 9f13b1e0537853d53b35c1e8e3136153db373e4e | |
parent | 5fe5557e8a8d3fd6a4617c2d8c863c1f62848020 (diff) | |
download | libgit2-5ca75fd52c36f63fe9b1218e79953411d4435a9d.tar.gz |
curl_stream: check for -1 after CURLINFO_LASTSOCKET
We're recently trying to upgrade to the current master of libgit2
in Cargo but we're unfortunately hitting a segfault in one of our
tests. This particular test is just a small smoke test that https
works (e.g. it's configured in libgit2). It attempts to clone
from a URL which simply immediately drops connections after
they're accepted (e.g. terminate abnormally). We expect to see a
standard error from libgit2 but unfortunately we're seeing a
segfault.
This segfault is happening inside of the `wait_for` function of
`curl_stream.c` at the line `FD_SET(fd, &errfd)` because `fd` is
-1. This ends up doing an out-of-bounds array access that faults
the program. I tracked back to where this -1 came from to the
line here (returned by `CURLINFO_LASTSOCKET`) and added a check
to return an error.
-rw-r--r-- | src/curl_stream.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/src/curl_stream.c b/src/curl_stream.c index 98de187dd..3a3f364b2 100644 --- a/src/curl_stream.c +++ b/src/curl_stream.c @@ -121,6 +121,11 @@ static int curls_connect(git_stream *stream) return seterr_curl(s); } + if (sockextr == -1) { + giterr_set(GITERR_NET, "curl socket is no longer valid"); + return -1; + } + s->socket = sockextr; if (s->parent.encrypted && failed_cert) @@ -198,6 +203,7 @@ static int wait_for(curl_socket_t fd, bool reading) FD_ZERO(&outfd); FD_ZERO(&errfd); + assert(fd >= 0); FD_SET(fd, &errfd); if (reading) FD_SET(fd, &infd); |