From: Jeremy Allison Date: Wed, 17 Jul 2019 22:21:21 +0000 (-0700) Subject: s3: smbd: Now we're using OpenDir_fsp() all the time, make sure we don't leak file... X-Git-Tag: tdb-1.4.2~357 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=84312fc5c289c926e189504b144bf9655491f706;p=thirdparty%2Fsamba.git s3: smbd: Now we're using OpenDir_fsp() all the time, make sure we don't leak file handles. We must always set dir_hnd->fsp, even in the fallback to SMB_VFS_OPENDIR() case. Remember if we had to fall back and fix the destructor to close the additional file descriptor if we did. Signed-off-by: Jeremy Allison Reviewed-by: Ralph Boehme --- diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 3646b7d744e..e4c348724ba 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -59,6 +59,7 @@ struct smb_Dir { unsigned int file_number; files_struct *fsp; /* Back pointer to containing fsp, only set from OpenDir_fsp(). */ + bool fallback_opendir; }; struct dptr_struct { @@ -1433,16 +1434,24 @@ static int smb_Dir_destructor(struct smb_Dir *dir_hnd) if (dir_hnd->dir != NULL) { SMB_VFS_CLOSEDIR(dir_hnd->conn, dir_hnd->dir); if (dir_hnd->fsp != NULL) { + files_struct *fsp = dir_hnd->fsp; /* * The SMB_VFS_CLOSEDIR above * closes the underlying fd inside - * dirp->fsp. + * dirp->fsp, unless fallback_opendir + * was set in which case the fd + * in dir_hnd->fsp->fh->fd isn't + * the one being closed. Close + * it separately. */ - dir_hnd->fsp->fh->fd = -1; - if (dir_hnd->fsp->dptr != NULL) { - SMB_ASSERT(dir_hnd->fsp->dptr->dir_hnd == + if (dir_hnd->fallback_opendir) { + SMB_VFS_CLOSE(fsp); + } + fsp->fh->fd = -1; + if (fsp->dptr != NULL) { + SMB_ASSERT(fsp->dptr->dir_hnd == dir_hnd); - dir_hnd->fsp->dptr->dir_hnd = NULL; + fsp->dptr->dir_hnd = NULL; } dir_hnd->fsp = NULL; } @@ -1690,6 +1699,15 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, errno = ENOMEM; goto fail; } + /* + * Remember if we used the fallback. + * We need to change the destructor + * to also close the fsp file descriptor + * in this case as it isn't the same + * one the directory handle uses. + */ + dir_hnd->fsp = fsp; + dir_hnd->fallback_opendir = true; } talloc_set_destructor(dir_hnd, smb_Dir_destructor);