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

Robert Lazarski edited comment on AXIS2C-1537 at 1/14/26 8:27 PM:
------------------------------------------------------------------

 Issue: HTTP server crashes during shutdown due to a race condition between the 
listener thread and the shutdown code.

  Root cause:
  1. axis2_http_server_stop() sets stopped=true and closes the listening socket
  2. accept() in the listener thread returns (because socket was closed)
  3. axis2_http_svr_thread_free() could be called concurrently, freeing 
svr_thread
  4. Listener thread accesses freed memory when checking svr_thread->worker

  Fix: Added a check for svr_thread->stopped immediately after accept() returns 
in axis2_http_svr_thread_run(). If stopped, the loop breaks before accessing 
any other svr_thread members, avoiding the use-after-free.

  socket = axutil_network_handler_svr_socket_accept(env, 
svr_thread->listen_socket);
  if(svr_thread->stopped)
  {
      if(socket != -1)
          axutil_network_handler_close_socket(env, socket);
      break;
  }

  All tests pass (HTTP transport tests, deployment tests).



was (Author: robertlazarski):
 Issue: HTTP server crashes during shutdown due to a race condition between the 
listener thread and the shutdown code.

  Root cause:
  1. axis2_http_server_stop() sets stopped=true and closes the listening socket
  2. accept() in the listener thread returns (because socket was closed)
  3. axis2_http_svr_thread_free() could be called concurrently, freeing 
svr_thread
  4. Listener thread accesses freed memory when checking svr_thread->worker

  Fix: Added a check for svr_thread->stopped immediately after accept() returns 
in axis2_http_svr_thread_run(). If stopped, the loop breaks before accessing 
any other svr_thread members, avoiding the use-after-free.

  socket = axutil_network_handler_svr_socket_accept(env, 
svr_thread->listen_socket);
  if(svr_thread->stopped)
  {
      if(socket != -1)
          axutil_network_handler_close_socket(env, socket);
      break;
  }

  All tests pass (HTTP transport tests, deployment tests).

✻ Cog

> HTTP server crashes during shutdown
> -----------------------------------
>
>                 Key: AXIS2C-1537
>                 URL: https://issues.apache.org/jira/browse/AXIS2C-1537
>             Project: Axis2-C
>          Issue Type: Bug
>          Components: transport/http
>    Affects Versions: 1.6.0
>         Environment: Linux + Windows
>            Reporter: Thomas Gentsch
>            Priority: Major
>              Labels: patch
>             Fix For: 2.0.0
>
>         Attachments: http_server_main.c.patch, http_svr_thread.c.patch
>
>
> I experience some infrequent crashes at stopping an Axis server using
>   axis2_http_server_stop(...);
>   axis2_transport_receiver_free(...);
> Now it looks to me as if
>  - axis2_http_server_stop() just closes the listening socket of the 
>    listener thread and sets "stopped" to true
>  - then, the listener thread (in axis2_http_svr_thread_run) returns 
>    from axutil_network_handler_svr_socket_accept()
>    and checks the worker:
>     if (!svr_thread->worker) ...
> But:
>  - axis2_transport_receiver_free() indirectly calls 
>    axis2_http_server_free() which in turn destroys and frees 
>    server_impl->svr_thread
> I'm not sure yet whether I understand this completely, but it looks as
> if then (depending on which thread is faster) the listener accessed
> memory now already freed.
> In a first approach I moved in my own server prog the
> axis2_transport_receiver_free() after starting the HTTP server, i.e.:
>   if(axis2_transport_receiver_start(srv, env) == AXIS2_FAILURE)
>   {
>     // err handling
>   }
>   printf("Listener returned\n");
>   axis2_transport_receiver_free(...);
> This changes things a bit, now the crash comes later in
>  axis2_http_svr_thread_run
>  axutil_thread_pool_get_thread(..., axis2_svr_thread_worker_func
>  ...
>  axutil_stream_free
> But the question is: Is it right that the listener continues at all
> after the accept() returns a failure?
> I have inserted another test for "stopped" and, if so, break the
> listener loop and, so far, it seems to be ok.
> axis2_http_svr_thread_run(...)
> {
>   ...
>   socket = (int)axutil_network_handler_svr_socket_accept(env,
>                 svr_thread-> listen_socket);
>   if(svr_thread->stopped)
>   {
>     break;
>   }
> Does that ring any bells? Could somebody more experienced please think
> about that scenario (while having a look into the code)?
> I'll do more testing and, hoping that all keeps working, create a defect
> +patch.



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

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to