Skip to content

Commit 188923f

Browse files
peffgitster
authored andcommitted
http: fix segfault in handle_curl_result
When we create an http active_request_slot, we can set its "results" pointer back to local storage. The http code will fill in the details of how the request went, and we can access those details even after the slot has been cleaned up. Commit 8809703 (http: factor out http error code handling) switched us from accessing our local results struct directly to accessing it via the "results" pointer of the slot. That means we're accessing the slot after it has been marked as finished, defeating the whole purpose of keeping the results storage separate. Most of the time this doesn't matter, as finishing the slot does not actually clean up the pointer. However, when using curl's multi interface with the dumb-http revision walker, we might actually start a new request before handing control back to the original caller. In that case, we may reuse the slot, zeroing its results pointer, and leading the original caller to segfault while looking for its results inside the slot. Instead, we need to pass a pointer to our local results storage to the handle_curl_result function, rather than relying on the pointer in the slot struct. This matches what the original code did before the refactoring (which did not use a separate function, and therefore just accessed the results struct directly). Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b81401c commit 188923f

File tree

3 files changed

+6
-6
lines changed

3 files changed

+6
-6
lines changed

http.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -744,10 +744,9 @@ char *get_remote_object_url(const char *url, const char *hex,
744744
return strbuf_detach(&buf, NULL);
745745
}
746746

747-
int handle_curl_result(struct active_request_slot *slot)
747+
int handle_curl_result(struct active_request_slot *slot,
748+
struct slot_results *results)
748749
{
749-
struct slot_results *results = slot->results;
750-
751750
if (results->curl_result == CURLE_OK) {
752751
credential_approve(&http_auth);
753752
return HTTP_OK;
@@ -818,7 +817,7 @@ static int http_request(const char *url, void *result, int target, int options)
818817

819818
if (start_active_slot(slot)) {
820819
run_active_slot(slot);
821-
ret = handle_curl_result(slot);
820+
ret = handle_curl_result(slot, &results);
822821
} else {
823822
error("Unable to start HTTP request for %s", url);
824823
ret = HTTP_START_FAILED;

http.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ extern int start_active_slot(struct active_request_slot *slot);
7878
extern void run_active_slot(struct active_request_slot *slot);
7979
extern void finish_active_slot(struct active_request_slot *slot);
8080
extern void finish_all_active_slots(void);
81-
extern int handle_curl_result(struct active_request_slot *slot);
81+
extern int handle_curl_result(struct active_request_slot *slot,
82+
struct slot_results *results);
8283

8384
#ifdef USE_CURL_MULTI
8485
extern void fill_active_slots(void);

remote-curl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ static int run_slot(struct active_request_slot *slot)
369369
slot->curl_result = curl_easy_perform(slot->curl);
370370
finish_active_slot(slot);
371371

372-
err = handle_curl_result(slot);
372+
err = handle_curl_result(slot, &results);
373373
if (err != HTTP_OK && err != HTTP_REAUTH) {
374374
error("RPC failed; result=%d, HTTP code = %ld",
375375
results.curl_result, results.http_code);

0 commit comments

Comments
 (0)