[PATCH] Fix rundown crashes

Jeremy Allison jra at samba.org
Wed Jul 19 18:25:08 UTC 2017


On Wed, Jul 19, 2017 at 04:14:12PM +0200, Volker Lendecke via samba-technical wrote:
> Hi!
> 
> Review appreciated!

Yep, can't see any other way to fix this.

RB+. Pushed.


> -- 
> SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
> phone: +49-551-370000-0, fax: +49-551-370000-9
> AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
> http://www.sernet.de, mailto:kontakt at sernet.de

> From 14c4145070e5ad48b000cdd852b4c57ae819e16a Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Wed, 19 Jul 2017 14:51:33 +0200
> Subject: [PATCH] smbd: Fix a connection run-down race condition
> 
> When we do a server exit with active aio jobs, we need to keep the
> aio state active for the helper thread. Right now I don't see another
> chance than to leak memory in this case. And, I don't really oversee
> how cancelling requests works in this case, but this does fix crashes
> seen at a customer site.
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/modules/vfs_default.c | 33 +++++++++++++++++++++++++++------
>  1 file changed, 27 insertions(+), 6 deletions(-)
> 
> diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
> index bf857b6b1ca..fbfe654f1fd 100644
> --- a/source3/modules/vfs_default.c
> +++ b/source3/modules/vfs_default.c
> @@ -750,6 +750,7 @@ struct vfswrap_pread_state {
>  
>  static void vfs_pread_do(void *private_data);
>  static void vfs_pread_done(struct tevent_req *subreq);
> +static int vfs_pread_state_destructor(struct vfswrap_pread_state *state);
>  
>  static struct tevent_req *vfswrap_pread_send(struct vfs_handle_struct *handle,
>  					     TALLOC_CTX *mem_ctx,
> @@ -790,6 +791,8 @@ static struct tevent_req *vfswrap_pread_send(struct vfs_handle_struct *handle,
>  	}
>  	tevent_req_set_callback(subreq, vfs_pread_done, req);
>  
> +	talloc_set_destructor(state, vfs_pread_state_destructor);
> +
>  	return req;
>  }
>  
> @@ -818,19 +821,23 @@ static void vfs_pread_do(void *private_data)
>  	SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
>  }
>  
> +static int vfs_pread_state_destructor(struct vfswrap_pread_state *state)
> +{
> +	return -1;
> +}
> +
>  static void vfs_pread_done(struct tevent_req *subreq)
>  {
>  	struct tevent_req *req = tevent_req_callback_data(
>  		subreq, struct tevent_req);
> -#ifdef WITH_PROFILE
>  	struct vfswrap_pread_state *state = tevent_req_data(
>  		req, struct vfswrap_pread_state);
> -#endif
>  	int ret;
>  
>  	ret = pthreadpool_tevent_job_recv(subreq);
>  	TALLOC_FREE(subreq);
>  	SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes);
> +	talloc_set_destructor(state, NULL);
>  	if (tevent_req_error(req, ret)) {
>  		return;
>  	}
> @@ -866,6 +873,7 @@ struct vfswrap_pwrite_state {
>  
>  static void vfs_pwrite_do(void *private_data);
>  static void vfs_pwrite_done(struct tevent_req *subreq);
> +static int vfs_pwrite_state_destructor(struct vfswrap_pwrite_state *state);
>  
>  static struct tevent_req *vfswrap_pwrite_send(struct vfs_handle_struct *handle,
>  					      TALLOC_CTX *mem_ctx,
> @@ -906,6 +914,8 @@ static struct tevent_req *vfswrap_pwrite_send(struct vfs_handle_struct *handle,
>  	}
>  	tevent_req_set_callback(subreq, vfs_pwrite_done, req);
>  
> +	talloc_set_destructor(state, vfs_pwrite_state_destructor);
> +
>  	return req;
>  }
>  
> @@ -934,19 +944,23 @@ static void vfs_pwrite_do(void *private_data)
>  	SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
>  }
>  
> +static int vfs_pwrite_state_destructor(struct vfswrap_pwrite_state *state)
> +{
> +	return -1;
> +}
> +
>  static void vfs_pwrite_done(struct tevent_req *subreq)
>  {
>  	struct tevent_req *req = tevent_req_callback_data(
>  		subreq, struct tevent_req);
> -#ifdef WITH_PROFILE
>  	struct vfswrap_pwrite_state *state = tevent_req_data(
>  		req, struct vfswrap_pwrite_state);
> -#endif
>  	int ret;
>  
>  	ret = pthreadpool_tevent_job_recv(subreq);
>  	TALLOC_FREE(subreq);
>  	SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes);
> +	talloc_set_destructor(state, NULL);
>  	if (tevent_req_error(req, ret)) {
>  		return;
>  	}
> @@ -979,6 +993,7 @@ struct vfswrap_fsync_state {
>  
>  static void vfs_fsync_do(void *private_data);
>  static void vfs_fsync_done(struct tevent_req *subreq);
> +static int vfs_fsync_state_destructor(struct vfswrap_fsync_state *state);
>  
>  static struct tevent_req *vfswrap_fsync_send(struct vfs_handle_struct *handle,
>  					     TALLOC_CTX *mem_ctx,
> @@ -1012,6 +1027,8 @@ static struct tevent_req *vfswrap_fsync_send(struct vfs_handle_struct *handle,
>  	}
>  	tevent_req_set_callback(subreq, vfs_fsync_done, req);
>  
> +	talloc_set_destructor(state, vfs_fsync_state_destructor);
> +
>  	return req;
>  }
>  
> @@ -1035,19 +1052,23 @@ static void vfs_fsync_do(void *private_data)
>  	state->vfs_aio_state.duration = nsec_time_diff(&end_time, &start_time);
>  }
>  
> +static int vfs_fsync_state_destructor(struct vfswrap_fsync_state *state)
> +{
> +	return -1;
> +}
> +
>  static void vfs_fsync_done(struct tevent_req *subreq)
>  {
>  	struct tevent_req *req = tevent_req_callback_data(
>  		subreq, struct tevent_req);
> -#ifdef WITH_PROFILE
>  	struct vfswrap_fsync_state *state = tevent_req_data(
>  		req, struct vfswrap_fsync_state);
> -#endif
>  	int ret;
>  
>  	ret = pthreadpool_tevent_job_recv(subreq);
>  	TALLOC_FREE(subreq);
>  	SMBPROFILE_BASIC_ASYNC_END(state->profile_basic);
> +	talloc_set_destructor(state, NULL);
>  	if (tevent_req_error(req, ret)) {
>  		return;
>  	}
> -- 
> 2.11.0
> 




More information about the samba-technical mailing list