View Issue Details

IDProjectCategoryView StatusLast Update
0004889libmicrohttpdthread poolpublic2017-04-11 22:00
Reportertomasheran Assigned ToChristian Grothoff Due Date
PrioritynormalSeveritycrashReproducibilityrandom
Status closedResolutionfixed 
PlatformAnyOSSolarisOS Version11.next
Product VersionGit master 
Target Version0.9.53Fixed in Version0.9.53 
Summary0004889: Race condition between MHD_cleanup_connections() and MHD_upgrade_action()
DescriptionWhen MHD_USE_THREAD_PER_CONNECTION option is set, MHD_upgrade_action() will eventually shutdown() given connection's socket_fd and assign MHD_INVALID_SOCKET to it.

When at the same time some other thread runs MHD_cleanup_connections() where there's this bit of a code:

2629 if (MHD_INVALID_SOCKET != pos->socket_fd)
2630 MHD_socket_close_chk_ (pos->socket_fd);

I.e. it first checks whether the pos->socket_fd is not MHD_INVALID_SOCKET and if not, it goes on to close it (and check that the close succeeded or at least didn't file with EBADF).

Because of the race-condition, pos->socket_fd can change from something valid to MHD_INVALID_SOCKET "between" lines 2629 and 2630, which will of course wreak havoc late (MHD_PANIC kind of havoc ;)).
Steps To Reproducetest_upgrade test seems to catch this fairly often on a slower (or busy) machine.
Additional InformationLocking the daemon->cleanup_connection_mutex in MHD_upgrade_action() fixes the issue for me but I am not the right person to decide whether that's not too coarse grained lock to take at that time.
TagsNo tags attached.

Activities

Christian Grothoff

2017-02-14 15:35

manager   ~0011751

This has already been fixed in Git in October:

https://gnunet.org/git/libmicrohttpd.git/commit/?id=7d0221189929a3251d956166f82b06c456b33ed9

tomasheran

2017-02-14 16:05

reporter   ~0011752

The race I see is between MHD_cleanup_connections() in daemon.c and MHD_upgrade_action() in response.c line 683.

Christian Grothoff

2017-02-14 16:11

manager   ~0011753

Yes, which is the one that the commit I quote resolves by _just_ calling shutdown and not closing the socket.

That said, there was a 2nd issue in this constellation which I just fixed in
8a84902f7447edd6f677dfa9983c16146dacc7c5

Also, if you use line numbers, please state exactly which version (or Git revision) you are referencing, otherwise it's a bit hard to figure out what you are talking about.

Issue History

Date ModifiedUsernameFieldChange
2017-02-10 13:59tomasheranNew Issue
2017-02-12 08:49Christian GrothoffStatusnew => acknowledged
2017-02-14 15:35Christian GrothoffNote Added: 0011751
2017-02-14 15:35Christian GrothoffAssigned To => Christian Grothoff
2017-02-14 15:35Christian GrothoffStatusacknowledged => resolved
2017-02-14 15:35Christian GrothoffResolutionopen => fixed
2017-02-14 15:35Christian GrothoffFixed in Version => 0.9.53
2017-02-14 15:35Christian GrothoffProduct Version => Git master
2017-02-14 15:35Christian GrothoffTarget Version => 0.9.53
2017-02-14 16:05tomasheranStatusresolved => feedback
2017-02-14 16:05tomasheranResolutionfixed => reopened
2017-02-14 16:05tomasheranNote Added: 0011752
2017-02-14 16:11Christian GrothoffNote Added: 0011753
2017-02-14 16:11Christian GrothoffStatusfeedback => resolved
2017-02-14 16:11Christian GrothoffResolutionreopened => fixed
2017-04-11 22:00Christian GrothoffStatusresolved => closed
2024-01-21 12:25Christian GrothoffCategorylibmicrohttpd multi-threaded operation => thread pool