[PATCH] Use a stackframe for memory management in _wbint_QueryGroupList

Jeremy Allison jra at samba.org
Thu Dec 7 20:00:15 UTC 2017


On Thu, Dec 07, 2017 at 07:04:42PM +0100, Andreas Schneider wrote:
> On Thursday, 7 December 2017 18:57:34 CET Jeremy Allison wrote:
> > On Thu, Dec 07, 2017 at 08:29:03AM +0100, Andreas Schneider via samba-
> technical wrote:
> > > Hi,
> > > 
> > > I'm fixing that function right now for 3.6 and saw that some TALLOC_FREE
> > > are missing. For master I decided to use a stackframe to make it simpler
> > > to clean up.
> > > 
> > > Please review and push if OK.
> > 
> > Is the talloc_steal() really needed ?
> 
> Ups, during fixing that I forgot to change this back to frame. So 
> talloc_array() should allocate on the frame that the array is freed on error 
> and talloc_move should move it in the end ...
> 
> > We already have:
> > 
> >   	result = talloc_array(r->out.groups, struct wbint_Principal,
> >   			      num_total);
> > 
> > (NB. result is allocated off r->out.groups) so doing:
> > 
> >  +	r->out.groups->principals = talloc_steal(r->out.groups, result);
> > 
> > is at best redundant. How does talloc_steal() react when
> > the target is the same as the parent ?
> > 
> > Also, I prefer talloc_move() (yeah I know, I invented it) as it
> > leaves the old pointer as NULL for safety :-).
> 
> Ok, I used talloc_move() now.
>  
> > Also, if you're fixing any real memory leaks here we probably need
> > a bug report for back-ports.
> 
> Not really, we allocate on talloc_tos() it probably doesn't live long enough, 
> but some error path directly free it and others don't. This just makes sure 
> every error path directly cleans up. I don't think we need a bug.
> 
> Updated patch attached.

LGTM. Pushed !





> -- 
> Andreas Schneider                   GPG-ID: CC014E3D
> Samba Team                             asn at samba.org
> www.samba.org

> From d6bbf9ff01ff7a57935264e7676ce177f5937223 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Wed, 6 Dec 2017 18:48:47 +0100
> Subject: [PATCH] s3:winbindd: Use a stackframe for memory management in
>  _wbint_QueryGroupList
> 
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
>  source3/winbindd/winbindd_dual_srv.c | 43 ++++++++++++++++++------------------
>  1 file changed, 22 insertions(+), 21 deletions(-)
> 
> diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
> index 797a9d95493..81fcf855847 100644
> --- a/source3/winbindd/winbindd_dual_srv.c
> +++ b/source3/winbindd/winbindd_dual_srv.c
> @@ -380,6 +380,7 @@ NTSTATUS _wbint_LookupGroupMembers(struct pipes_struct *p,
>  NTSTATUS _wbint_QueryGroupList(struct pipes_struct *p,
>  			       struct wbint_QueryGroupList *r)
>  {
> +	TALLOC_CTX *frame = NULL;
>  	struct winbindd_domain *domain = wb_child_domain();
>  	uint32_t i;
>  	uint32_t num_local_groups = 0;
> @@ -389,13 +390,15 @@ NTSTATUS _wbint_QueryGroupList(struct pipes_struct *p,
>  	uint32_t ti = 0;
>  	uint64_t num_total = 0;
>  	struct wbint_Principal *result;
> -	NTSTATUS status;
> +	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
>  	bool include_local_groups = false;
>  
>  	if (domain == NULL) {
>  		return NT_STATUS_REQUEST_NOT_ACCEPTED;
>  	}
>  
> +	frame = talloc_stackframe();
> +
>  	switch (lp_server_role()) {
>  	case ROLE_ACTIVE_DIRECTORY_DC:
>  		if (domain->internal) {
> @@ -416,32 +419,33 @@ NTSTATUS _wbint_QueryGroupList(struct pipes_struct *p,
>  	}
>  
>  	if (include_local_groups) {
> -		status = wb_cache_enum_local_groups(domain, talloc_tos(),
> +		status = wb_cache_enum_local_groups(domain, frame,
>  						    &num_local_groups,
>  						    &local_groups);
>  		reset_cm_connection_on_error(domain, status);
>  		if (!NT_STATUS_IS_OK(status)) {
> -			return status;
> +			goto out;
>  		}
>  	}
>  
> -	status = wb_cache_enum_dom_groups(domain, talloc_tos(),
> +	status = wb_cache_enum_dom_groups(domain, frame,
>  					  &num_dom_groups,
>  					  &dom_groups);
>  	reset_cm_connection_on_error(domain, status);
>  	if (!NT_STATUS_IS_OK(status)) {
> -		return status;
> +		goto out;
>  	}
>  
>  	num_total = num_local_groups + num_dom_groups;
>  	if (num_total > UINT32_MAX) {
> -		return NT_STATUS_INTERNAL_ERROR;
> +		status = NT_STATUS_INTERNAL_ERROR;
> +		goto out;
>  	}
>  
> -	result = talloc_array(r->out.groups, struct wbint_Principal,
> -			      num_total);
> +	result = talloc_array(frame, struct wbint_Principal, num_total);
>  	if (result == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> +		status = NT_STATUS_NO_MEMORY;
> +		goto out;
>  	}
>  
>  	for (i = 0; i < num_local_groups; i++) {
> @@ -452,14 +456,11 @@ NTSTATUS _wbint_QueryGroupList(struct pipes_struct *p,
>  		rg->type = SID_NAME_ALIAS;
>  		rg->name = talloc_strdup(result, lg->acct_name);
>  		if (rg->name == NULL) {
> -			TALLOC_FREE(result);
> -			TALLOC_FREE(dom_groups);
> -			TALLOC_FREE(local_groups);
> -			return NT_STATUS_NO_MEMORY;
> +			status = NT_STATUS_NO_MEMORY;
> +			goto out;
>  		}
>  	}
>  	num_local_groups = 0;
> -	TALLOC_FREE(local_groups);
>  
>  	for (i = 0; i < num_dom_groups; i++) {
>  		struct wb_acct_info *dg = &dom_groups[i];
> @@ -469,19 +470,19 @@ NTSTATUS _wbint_QueryGroupList(struct pipes_struct *p,
>  		rg->type = SID_NAME_DOM_GRP;
>  		rg->name = talloc_strdup(result, dg->acct_name);
>  		if (rg->name == NULL) {
> -			TALLOC_FREE(result);
> -			TALLOC_FREE(dom_groups);
> -			TALLOC_FREE(local_groups);
> -			return NT_STATUS_NO_MEMORY;
> +			status = NT_STATUS_NO_MEMORY;
> +			goto out;
>  		}
>  	}
>  	num_dom_groups = 0;
> -	TALLOC_FREE(dom_groups);
>  
>  	r->out.groups->num_principals = ti;
> -	r->out.groups->principals = result;
> +	r->out.groups->principals = talloc_move(r->out.groups, &result);
>  
> -	return NT_STATUS_OK;
> +	status = NT_STATUS_OK;
> +out:
> +	TALLOC_FREE(frame);
> +	return status;
>  }
>  
>  NTSTATUS _wbint_QueryUserRidList(struct pipes_struct *p,
> -- 
> 2.15.1
> 




More information about the samba-technical mailing list