[PATCH] fix use after free in smbd
Michael Adam
obnox at samba.org
Wed Mar 16 23:59:52 UTC 2016
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.
Thanks - Michael
-------------- next part --------------
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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20160317/df8d5a05/signature.sig>
More information about the samba-technical
mailing list