[ 
https://issues.apache.org/jira/browse/SERF-195?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17987047#comment-17987047
 ] 

Branko Čibej commented on SERF-195:
-----------------------------------

Bugfix [branch|https://svn.apache.org/repos/asf/serf/branches/SERF-195].

> [PATCH] time-consuming operations in auth_ module leads to memory corruption
> ----------------------------------------------------------------------------
>
>                 Key: SERF-195
>                 URL: https://issues.apache.org/jira/browse/SERF-195
>             Project: serf
>          Issue Type: Bug
>    Affects Versions: serf-1.4.0, serf-trunk
>            Reporter: Alex W
>            Assignee: Branko Čibej
>            Priority: Major
>         Attachments: linked-list-fix.patch
>
>
> In serf trunk and 1.4.x, doing time-consuming operations in an auth module's 
> "setup" function can lead to memory corruption and crashes. I strongly 
> suspect this can be triggered in other ways as well, if they can lead to 
> delayed requests, timeouts or errors on the server, etc. You can easily 
> reproduce this (pretty reliably) by making a change such as:
> {noformat}
> diff a/auth/auth_basic.c b/auth/auth_basic.c
> --- a/auth/auth_basic.c
> +++ b/auth/auth_basic.c
> @@ -169,6 +169,7 @@ serf__setup_request_basic_auth(const serf__authn_scheme_t 
> *scheme,
>      basic_info = authn_info->baton;
>  
>      if (basic_info && basic_info->header && basic_info->value) {
> +        usleep(75000);
>          serf_bucket_headers_setn(hdrs_bkt, basic_info->header,
>                                   basic_info->value);
>          return APR_SUCCESS;
> {noformat}
> And then using serf via e.g. {{svn co}} of a large repository.
> The crash which occurs results from the {{written_reqs}} and 
> {{unwritten_reqs}} lists on the {{serf_connection_t}} containing invalid 
> pointers. Generally, since the memory is pooled, we don't notice the 
> corruption until teardown time. If you run with pool debugging and valgrind 
> you can eventually narrow down the cause to the linked lists.
> Several places which manipulate the linked lists are suspicious, e.g. this 
> section in {{outgoing.c}}:
> {noformat}
>         serf__link_requests(&conn->written_reqs, &conn->written_reqs_tail,
>                             request);
>         conn->nr_of_written_reqs++;
>         conn->unwritten_reqs = conn->unwritten_reqs->next;
>         conn->nr_of_unwritten_reqs--;
>         request->next = NULL;
> {noformat}
> This assumes (but never checks) that the request in question is at the front 
> of the {{unwritten_reqs}} list, which can be violated in both error cases and 
> in cases of aborted requests. The ordering of operations here (link the 
> request onto the new list, then unlink it from the old one) should also make 
> a reader pretty suspicious, though in this particular case it shouldn't be a 
> problem (since {{serf__link_requests}} doesn't actually change the {{next}} 
> pointer). There are also other sections of linked list code too which are a 
> little questionable.
> I'm attaching a patch which reorganises the {{written_reqs}} and 
> {{unwritten_reqs}} lists into their own structs and provides higher-level 
> functions for manipulating them. These also add assertions to make sure that 
> the correct list is being used. I also check conditions in places such as 
> this section of {{outgoing.c}} for other error cases. After these changes I 
> can no longer reproduce the incorrect free() or other crashes with a slow 
> auth plugin.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to