From 00a26ac9856d4ec483736ae7c4bf17d08feed5f8 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 21 Mar 2018 20:41:44 +0100 Subject: [PATCH] smbd: deal with fsp->aio_requests in close_directory() Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- source3/smbd/close.c | 25 +++++++++++++++++++++++++ source3/smbd/smb2_query_directory.c | 8 ++++++++ 2 files changed, 33 insertions(+) diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 8581b04e8aa..7820fff3519 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -1085,6 +1085,31 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, notify_status = NT_STATUS_OK; } + if (fsp->num_aio_requests != 0) { + if (close_type != SHUTDOWN_CLOSE) { + /* + * We panic here because if we close() the fd while we + * have outstanding async I/O requests, an async IO + * request might use the fd. For directories the fd is + * read-only, so this is not as bad as with files, but + * still, better safe then sorry. + */ + DBG_ERR("fsp->num_aio_requests=%u\n", + fsp->num_aio_requests); + smb_panic("close with outstanding aio requests"); + return NT_STATUS_INTERNAL_ERROR; + } + + while (fsp->num_aio_requests != 0) { + /* + * The destructor of the req will remove itself from the + * fsp. Don't use TALLOC_FREE here, this will overwrite + * what the destructor just wrote into aio_requests[0]. + */ + talloc_free(fsp->aio_requests[0]); + } + } + /* * NT can set delete_on_close of the last open * reference to a directory also. diff --git a/source3/smbd/smb2_query_directory.c b/source3/smbd/smb2_query_directory.c index 1a7137ce879..3c241f2e04a 100644 --- a/source3/smbd/smb2_query_directory.c +++ b/source3/smbd/smb2_query_directory.c @@ -253,6 +253,7 @@ static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx, struct tm tm; char *p; bool stop = false; + bool ok; req = tevent_req_create(mem_ctx, &state, struct smbd_smb2_query_directory_state); @@ -516,6 +517,13 @@ static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } + ok = aio_add_req_to_fsp(fsp, req); + if (!ok) { + DBG_ERR("Could not add req to fsp\n"); + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return tevent_req_post(req, ev); + } + return req; }