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)`.

Reply via email to