diff options
author | Jeremy Allison <jra@samba.org> | 2008-10-08 11:40:16 -0700 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2008-10-15 18:49:17 +0200 |
commit | 15b2f1d8744d157b131a0441e8738d8519de37c7 (patch) | |
tree | d823b50ebd50465a32bbb2bd2889800f65c5dcf9 | |
parent | ed955214133c264865d2f6ca532349f0c1ea8d4b (diff) | |
download | samba-15b2f1d8744d157b131a0441e8738d8519de37c7.tar.gz samba-15b2f1d8744d157b131a0441e8738d8519de37c7.tar.xz samba-15b2f1d8744d157b131a0441e8738d8519de37c7.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.
(cherry picked from commit ce8de496ec139b7a56db20c5ffbcbdc2f4db0a51)
-rw-r--r-- | source/winbindd/winbindd_dual.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/source/winbindd/winbindd_dual.c b/source/winbindd/winbindd_dual.c index de6ad61a112..acf0908657d 100644 --- a/source/winbindd/winbindd_dual.c +++ b/source/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); } |