diff options
| author | Jeremy Allison <jra@samba.org> | 2008-10-08 11:39:32 -0700 | 
|---|---|---|
| committer | Jeremy Allison <jra@samba.org> | 2008-10-08 11:39:32 -0700 | 
| commit | 14f835ba4b7e553d0cd75f3b311378c5c875e87c (patch) | |
| tree | 8cc684817569631a8af4ece04d3e6776c22d4338 | |
| parent | be63f86ce7029b0a4efbe1478cc16189b5d26aec (diff) | |
| download | samba-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.
| -rw-r--r-- | source3/winbindd/winbindd_dual.c | 23 | 
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);  }  | 
