CC += Bert Huijben, probably he knows the area best
On 08.10.2021 4:08, Alexandr Miloslavskiy wrote:
I'm trying serf from branch 1.4.x.
I couldn't use 1.3.9 because I also need to use OpenSSL 1.1.
I have encountered a segfault and debugged. To my understanding, the
crashing code comes from this commit:
r1712776 by Bert Huijben, 2015-11-05 17:05:02
Hard to say if the commit introduced the problem or merely shuffled the
code around. At any rate, the crash is not reproducible with serf 1.3.9.
I have debugged, see analysis below. However, without knowledge of serf,
I can't quickly figure how to fix.
Hopefully Bert could do that?
Analysis:
---------
1) I'm trying to connect SVN to an HTTPS server using a client cert.
2) I'm using a wrong password for the certificate.
3) In `ssl_decrypt()`
It detects error in `SSL_read()` and propagates error.
Stack:
libsvn_ra_1!ssl_decrypt
libsvn_ra_1!common_databuf_prep
libsvn_ra_1!serf_databuf_peek
libsvn_ra_1!read_from_connection
libsvn_ra_1!process_connection
libsvn_ra_1!serf__process_connection
libsvn_ra_1!serf_context_run
libsvn_ra_1!svn_ra_serf__context_run_wait
libsvn_ra_1!svn_ra_serf__exchange_capabilities
libsvn_ra_1!svn_ra_serf__open
libsvn_ra_1!svn_ra_open5
libsvn_client_1!svn_client__open_ra_session_internal
libsvn_client_1!svn_client__ra_session_from_path2
libsvn_client_1!svn_client_info4
4) In `svn_ra_open5()`
calls `svn_pool_destroy(sesspool)`
5) In `svn_pool_destroy()`
calls the registered `clean_resp()`
6) In `clean_resp()`
Sets `request->respool` to NULL.
(request->writing == SERF_WRITING_STARTED)
calls `serf__connection_pre_cleanup()`
7) In `serf__connection_pre_cleanup()`
It has loop for `conn->done_reqs`.
loop handles exactly one request, the one already in `clean_resp()`
loop sets `rq->writing` to `SERF_WRITING_FINISHED`
loop calls `serf__destroy_request()`
8) In `serf__destroy_request()`
`rq->writing` is already `SERF_WRITING_FINISHED` (see #7)
Therefore, it's time to clean things.
`request->respool` is null (see #6).
`request` is freed via `serf_bucket_mem_free()`.
9) Back to `clean_resp()`
Segfaults on `if (request->resp_bkt)`.