libvirt/tests/virnetdaemondata
Marc Hartmayer 94bbbcee1f rpc: virnetserver: Fix race on srv->nclients_unauth
There is a race between virNetServerProcessClients (main thread) and
remoteDispatchAuthList/remoteDispatchAuthPolkit/remoteSASLFinish (worker
thread) that can lead to decrementing srv->nclients_unauth when it's
zero. Since virNetServerCheckLimits relies on the value
srv->nclients_unauth the underrun causes libvirtd to stop accepting
new connections forever.

Example race scenario (assuming libvirtd is using policykit and the
client is privileged):
  1. The client calls the RPC remoteDispatchAuthList =>
     remoteDispatchAuthList is executed on a worker thread (Thread
     T1). We're assuming now the execution stops for some time before
     the line 'virNetServerClientSetAuth(client, 0)'
  2. The client closes the connection irregularly. This causes the
     event loop to wake up and virNetServerProcessClient to be
     called (on the main thread T0). During the
     virNetServerProcessClients the srv lock is hold. The condition
     virNetServerClientNeedAuth(client) will be checked and as the
     authentication is not finished right now
     virNetServerTrackCompletedAuthLocked(srv) will be called =>
     --srv->nclients_unauth => 0
  3. The Thread T1 continues, marks the client as authenticated, and
     calls virNetServerTrackCompletedAuthLocked(srv) =>
     --srv->nclients_unauth => --0 => wrap around as nclient_unauth is
     unsigned
  4. virNetServerCheckLimits(srv) will disable the services forever

To fix it, add an auth_pending field to the client struct so that it
is now possible to determine if the authentication process has already
been handled for this client.

Setting the authentication method to none for the client in
virNetServerProcessClients is not a proper way to indicate that the
counter has been decremented, as this would imply that the client is
authenticated.

Additionally, adjust the existing test cases for this new field.

Signed-off-by: Marc Hartmayer <mhartmay@linux.vnet.ibm.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.vnet.ibm.com>
2018-01-04 06:55:31 -05:00
..
input-data-admin-nomdns.json
input-data-admin-server-names.json
input-data-anon-clients.json
input-data-client-ids.json rpc: virnetserverclient: Identify clients by an integer ID 2016-05-02 22:25:51 +02:00
input-data-client-timestamp.json rpc: virnetserverclient: Introduce new attribute conn_time to client 2016-05-02 22:25:52 +02:00
input-data-initial-nomdns.json
input-data-initial.json
input-data-no-keepalive-required.json
output-data-admin-nomdns.json rpc: virnetserver: Fix race on srv->nclients_unauth 2018-01-04 06:55:31 -05:00
output-data-admin-server-names.json rpc: virnetserver: Fix race on srv->nclients_unauth 2018-01-04 06:55:31 -05:00
output-data-anon-clients.json rpc: virnetserver: Fix race on srv->nclients_unauth 2018-01-04 06:55:31 -05:00
output-data-client-ids.json rpc: virnetserver: Fix race on srv->nclients_unauth 2018-01-04 06:55:31 -05:00
output-data-client-timestamp.json rpc: virnetserver: Fix race on srv->nclients_unauth 2018-01-04 06:55:31 -05:00
output-data-initial-nomdns.json rpc: virnetserver: Fix race on srv->nclients_unauth 2018-01-04 06:55:31 -05:00
output-data-initial.json rpc: virnetserver: Fix race on srv->nclients_unauth 2018-01-04 06:55:31 -05:00
output-data-no-keepalive-required.json rpc: virnetserver: Fix race on srv->nclients_unauth 2018-01-04 06:55:31 -05:00
README

   virnetservertest data files
   ===========================

The various input-data-*.json files are a record of all the historical
formats that libvirt has been able to produce data for. Everytime a
new field is added to the JSON output, a *new* input data file should
be created. We must not add new fields to existing input-data files,
nor must we ever re-structure them if code changes, as we must check
new code handles the legacy formats.

The various output-data-*.json files are the record of what the *new*
JSON output should look like for the correspondingly named input-data
file. It is permissible to change the existing output-data-*.json
files if the format we save in is updated.