[PATCH] fix use after free in smbd
Jeremy Allison
jra at samba.org
Thu Mar 17 00:06:42 UTC 2016
On Thu, Mar 17, 2016 at 12:59:52AM +0100, Michael Adam wrote:
> Hi,
>
> Writing a new test case to instrument the
> durable reconnect code more, we observed a
> segfault would occur now and then. The analysis
> showed a use-after free:
>
> vfs_default_durable_reconnect():
> fsp_new() ==> this does DLIST_ADD(fsp->conn->sconn->files, fsp)
> if (fsp->oplock_type == LEASE_OPLOCK) {
> find_fsp_lease(fsp, &key, l) ==> this fills conn->fsp_fi_cache
> if (client guids not equal) {
> fsp_free(fsp) ==> this does DLIST_REMOVE(fsp->conn->sconn->files, fsp)
> }
>
> so after this code we have the fsp_fi_cache still pointing to the
> free'd memory. The next call to find_fsp_lease will use the cache
> and hence access the freed memory.
>
> Attached find a patch to fix this use-after-free.
>
> The fix consists in invalidating the cache in fsp_free() instead
> of just in its wrapper file_free().
>
> Review appreciated.
LGTM, pushed as I just created the same patch :-).
> From c51c3717709dfcbff6960513155de8df19276c57 Mon Sep 17 00:00:00 2001
> From: Michael Adam <obnox at samba.org>
> Date: Wed, 16 Mar 2016 23:57:33 +0100
> Subject: [PATCH] smbd: fix use after free via conn->fsp_fi_cache
>
> Some instrumentation of the the durable reconnect
> code uncovered a problem in the fsp_new, fsp_free pair:
>
> vfs_default_durable_reconnect():
> fsp_new() ==> this does DLIST_ADD(fsp->conn->sconn->files, fsp)
> if (fsp->oplock_type == LEASE_OPLOCK) {
> find_fsp_lease(fsp, &key, l) ==> this fills conn->fsp_fi_cache
> if (client guids not equal) {
> fsp_free(fsp) ==> this does DLIST_REMOVE(fsp->conn->sconn->files, fsp)
> }
>
> so after this code we have the fsp_fi_cache still pointing to the
> free'd memory. The next call to find_fsp_lease will use the cache
> and hence access the freed memory.
>
> The fix consists in invalidating the cache in fsp_free() instead
> of just in its wrapper file_free().
>
> BUG: https://bugzilla.samba.org/show_bug.cgi?id=11799
>
> Pair-Programmed-With: Guenther Deschner <gd at samba.org>
>
> Signed-off-by: Michael Adam <obnox at samba.org>
> Signed-off-by: Guenther Deschner <gd at samba.org>
> ---
> source3/smbd/files.c | 9 ++++-----
> 1 file changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/source3/smbd/files.c b/source3/smbd/files.c
> index 8fefddd..3e2b3d7 100644
> --- a/source3/smbd/files.c
> +++ b/source3/smbd/files.c
> @@ -478,6 +478,10 @@ void fsp_free(files_struct *fsp)
> {
> struct smbd_server_connection *sconn = fsp->conn->sconn;
>
> + if (fsp == sconn->fsp_fi_cache.fsp) {
> + ZERO_STRUCT(sconn->fsp_fi_cache);
> + }
> +
> DLIST_REMOVE(sconn->files, fsp);
> SMB_ASSERT(sconn->num_files > 0);
> sconn->num_files--;
> @@ -540,11 +544,6 @@ void file_free(struct smb_request *req, files_struct *fsp)
> remove_smb2_chained_fsp(fsp);
> }
>
> - /* Closing a file can invalidate the positive cache. */
> - if (fsp == sconn->fsp_fi_cache.fsp) {
> - ZERO_STRUCT(sconn->fsp_fi_cache);
> - }
> -
> /* Drop all remaining extensions. */
> vfs_remove_all_fsp_extensions(fsp);
>
> --
> 2.5.0
>
More information about the samba-technical
mailing list