summaryrefslogtreecommitdiff
path: root/lib/util/blocking.c
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2011-08-26 16:54:18 +0200
committerVolker Lendecke <vlendec@samba.org>2011-08-26 18:51:24 +0200
commited058f4dc3e059967f3c0538bc220866e9c63588 (patch)
treef9fee3bea1981c73ad526bb386aa2607e4af1c47 /lib/util/blocking.c
parentb72944fea743ec187750239568ba904c7fad653f (diff)
downloadsamba-ed058f4dc3e059967f3c0538bc220866e9c63588.tar.gz
samba-ed058f4dc3e059967f3c0538bc220866e9c63588.tar.bz2
samba-ed058f4dc3e059967f3c0538bc220866e9c63588.zip
s3: Fix a winbind race leading to 100% CPU
This fixes a race condition that leads to the winbindd_children list becoming corrupted. It happens when on a busy winbind SIGCHLD is a bit late. Imagine a winbind with multiple requests in the queue for a single child. Child dies, and before the SIGCHLD handler is called we find the socket to be dead. wb_child_request_done is called, receiving an error from wb_simple_trans_recv. It closes the socket. Then immediately the wb_child_request_trigger will do another fork_domain_child before the signal handler is called. This means that we do another fork_domain_child, we have child->sock==-1 at this point. fork_domain_child will do a DLIST_ADD(winbindd_children, child) a second time where the child is already part of that list. This corrupts the list. Then the signal handler kicks in, spinning in for (child = winbindd_children; child != NULL; child = child->next) { forever. Not good. This patch makes sure that both conditions (sock==-1 and not part of the list) for a winbindd_child struct match up. Autobuild-User: Volker Lendecke <vlendec@samba.org> Autobuild-Date: Fri Aug 26 18:51:24 CEST 2011 on sn-devel-104
Diffstat (limited to 'lib/util/blocking.c')
0 files changed, 0 insertions, 0 deletions