summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2008-10-08 11:39:32 -0700
committerJeremy Allison <jra@samba.org>2008-10-08 11:39:32 -0700
commit14f835ba4b7e553d0cd75f3b311378c5c875e87c (patch)
tree8cc684817569631a8af4ece04d3e6776c22d4338 /source3
parentbe63f86ce7029b0a4efbe1478cc16189b5d26aec (diff)
downloadsamba-14f835ba4b7e553d0cd75f3b311378c5c875e87c.tar.gz
samba-14f835ba4b7e553d0cd75f3b311378c5c875e87c.tar.bz2
samba-14f835ba4b7e553d0cd75f3b311378c5c875e87c.zip
Fix bug #5814 - Winbindd dumping core in a strange manner while doing "rescan_trusted_domain".
From analysis by hargagan <shargagan@novell.com> : "The winbindd_child_died() is also getting called from process_loop() in case of SIGCHLD signal. In this case it doesn't make the timeout_handler to NULL for the first request. It then initiate a new request using schedule_async_request() which installs a new timeout handler for the same request. In such a case, for a badly unresponsive system both the timeout handler can be called. For the first call the "private_data" will be cleared and for another call the timeout handler will be detecting the double free. So, for such a case as well, the winbindd_child_died() should make the timeout_handler to NULL." Jeremy.
Diffstat (limited to 'source3')
-rw-r--r--source3/winbindd/winbindd_dual.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index f6a9c1f26d..aeb52d9b5a 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -300,6 +300,18 @@ static void schedule_async_request(struct winbindd_child *child)
return; /* Busy */
}
+ /*
+ * This may be a reschedule, so we might
+ * have an existing timeout event pending on
+ * the first entry in the child->requests list
+ * (we only send one request at a time).
+ * Ensure we free it before we reschedule.
+ * Bug #5814, from hargagan <shargagan@novell.com>.
+ * JRA.
+ */
+
+ TALLOC_FREE(request->reply_timeout_event);
+
if ((child->pid == 0) && (!fork_domain_child(child))) {
/* fork_domain_child failed.
Cancel all outstanding requests */
@@ -495,6 +507,17 @@ void winbind_child_died(pid_t pid)
child->event.flags = 0;
child->pid = 0;
+ if (child->requests) {
+ /*
+ * schedule_async_request() will also
+ * clear this event but the call is
+ * idempotent so it doesn't hurt to
+ * cover all possible future code
+ * paths. JRA.
+ */
+ TALLOC_FREE(child->requests->reply_timeout_event);
+ }
+
schedule_async_request(child);
}