summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorGerald W. Carter <jerry@samba.org>2008-04-30 10:09:43 -0500
committerGerald W. Carter <jerry@samba.org>2008-04-30 10:09:43 -0500
commitc413c97ff4b646a260bc4665069f4e99d50ecd1c (patch)
tree2f2980009a29287cb9d593595a192495ba66a996 /source3
parent43c079ef26b6c5c1ee3c22c72d800d6131396993 (diff)
downloadsamba-c413c97ff4b646a260bc4665069f4e99d50ecd1c.tar.gz
samba-c413c97ff4b646a260bc4665069f4e99d50ecd1c.tar.bz2
samba-c413c97ff4b646a260bc4665069f4e99d50ecd1c.zip
Winbind: Prevent cycle in children list when reaping dead child processes.
Thanks to Glenn Curtis and Kyle Stemen @ Likewise. Their explanation is: In winbindd_dual.c, there is a list of children processes that is maintained using macros DTLIST_ADD and DTLIST_REMOVE. In the case when a scheduled_async_request fails, the particular child was located in the list, and its attributes were cleared out and it was reused for a subsequent async request. The bug was that the new request would queue the same node into the doubly-linked list and would result in list->next pointing to the same node as list itself. This would set up an infinite loop in the processing of the for loop when the list of children was referenced. Solution was to fully remove the child node from the list, such that it could be inserted without risk of being inserted twice. Note that the child is re-added to the list in fork_domain_child() again. (This used to be commit b379b5b5d8a6daccc69aaf2be6d9a6e276e7dd78)
Diffstat (limited to 'source3')
-rw-r--r--source3/winbindd/winbindd_dual.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index 14ba38cef3..f71eec56f6 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -478,6 +478,10 @@ void winbind_child_died(pid_t pid)
return;
}
+ /* This will be re-added in fork_domain_child() */
+
+ DLIST_REMOVE(children, child);
+
remove_fd_event(&child->event);
close(child->event.fd);
child->event.fd = 0;