[PATCH] Fixes for winbindd

Andrew Bartlett abartlet at samba.org
Fri Jul 25 14:26:18 MDT 2014


On Fri, 2014-07-25 at 12:19 +0200, Volker Lendecke wrote:
> On Fri, Jul 25, 2014 at 02:41:10PM +1200, Garming Sam wrote:
> > Hi,
> > 
> > During an auto-build, we managed to come across a segfault in
> > winbindd as a result of an RODC DNS update.
> > 
> > We have to ensure that the dns_names parameter is preserved on a
> > long term memory context.
> > 
> > The second patch fixes a use after free error when the first error happens.
> > 
> > 
> > Please review and push.
> > 
> > 
> > Cheers,
> > 
> > 
> > Garming Sam
> 
> > >From 5bc91f9e43f44e0476c1083a8bd5145c094492f8 Mon Sep 17 00:00:00 2001
> > From: Andrew Bartlett <abartlet at samba.org>
> > Date: Thu, 24 Jul 2014 15:54:58 +1200
> > Subject: [PATCH 1/2] libcli/auth: Ensure that the dns_names in/out parameter
> >  is preserved
> > 
> > This is in dcerpc_netr_DsrUpdateReadOnlyServerDnsRecords, which has
> > status variables filled in by the server and placed in this in/out
> > array.
> > 
> > This showed up as a segfault in winbindd during RODC DNS update.
> > 
> > Andrew Bartlett
> > 
> > Signed-off-by: Garming Sam <garming at catalyst.net.nz>
> > Signed-off-by: Andrew Bartlett <abartlet at samba.org>
> > Pair-programmed-with: Garming Sam <garming at catalyst.net.nz>
> > ---
> >  libcli/auth/netlogon_creds_cli.c | 9 ++++++++-
> >  1 file changed, 8 insertions(+), 1 deletion(-)
> > 
> > diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c
> > index d709e6a..a461dc6 100644
> > --- a/libcli/auth/netlogon_creds_cli.c
> > +++ b/libcli/auth/netlogon_creds_cli.c
> > @@ -2754,7 +2754,14 @@ static void netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords_done(struct tev
> >  	NTSTATUS result;
> >  	bool ok;
> >  
> > -	status = dcerpc_netr_DsrUpdateReadOnlyServerDnsRecords_recv(subreq, state,
> > +	/*
> > +	 * We use state->dns_names as the memory context, as this is
> > +	 * the only in/out variable and it has been overwritten by the
> > +	 * out parameter from the server.
> > +	 *
> > +	 * We need to preserve the return value until the caller can use it.
> > +	 */
> > +	status = dcerpc_netr_DsrUpdateReadOnlyServerDnsRecords_recv(subreq, state->dns_names,
> 
> Can you explain that a bit more closely? As far as I can
> see, netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords is
> only used in a synchronous fashion. And as "state" lives as
> long as the sync function ponders the request, at least
> inside that function this should not make a difference. What
> is the sequence of talloc_free()'s that leads to the
> segfault you saw?

netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords_send() creates
state on mem_ctx, which is frame in
netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords()

	struct netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords_state *state;
	struct tevent_req *subreq;

	req = tevent_req_create(mem_ctx, &state,
				struct netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords_state);
	if (req == NULL) {
		return NULL;
	}

The state->dns_names is an in/out parameter as dns_names to
netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords() and has a longer
life time. 

The issue isn't the async, it is that the memory needs to be around
longer than the state variable.

The typical approach of a talloc_steal won't work, due to the way the
ref variable is overwritten.  The struct NL_DNS_NAME_INFO_ARRAY
dns_names is the original input array, but the elements are overwritten
in dcerpc_netr_DsrUpdateReadOnlyServerDnsRecords_done()

> > As found during investigation of the previous commit, when the RPC
> > call fails totally, we must only try and send one error reply.
> > 
> > Andrew Bartlett
> > 
> > Signed-off-by: Andrew Bartlett <abartlet at samba.org>
> > Signed-off-by: Garming Sam <garming at catalyst.net.nz>
> > Pair-programmed-with: Garming Sam <garming at catalyst.net.nz>
> > ---
> >  source3/winbindd/winbindd_irpc.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/source3/winbindd/winbindd_irpc.c b/source3/winbindd/winbindd_irpc.c
> > index cf58a08..aeaea71 100644
> > --- a/source3/winbindd/winbindd_irpc.c
> > +++ b/source3/winbindd/winbindd_irpc.c
> > @@ -51,6 +51,7 @@ static void wb_irpc_forward_callback(struct tevent_req *subreq)
> >  		DEBUG(0,("RPC callback failed for %s - %s\n",
> >  			 opname, nt_errstr(status)));
> >  		irpc_send_reply(st->msg, status);
> > +		return;
> >  	}
> >  
> >  	irpc_send_reply(st->msg, status);
> 
> Reviewed-by: Me.

Thanks,

Andrew Bartlett

-- 
Andrew Bartlett                       http://samba.org/~abartlet/
Authentication Developer, Samba Team  http://samba.org
Samba Developer, Catalyst IT          http://catalyst.net.nz/services/samba




More information about the samba-technical mailing list