Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 24 Feb 2023 15:37:32 GMT
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 4036fcb8053a - main - nfsd: Fix a use after free when vnet prisons are deleted
Message-ID:  <202302241537.31OFbWAo034841@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by rmacklem:

URL: https://cgit.FreeBSD.org/src/commit/?id=4036fcb8053adf3ac54c8428eef0dd076dfc1718

commit 4036fcb8053adf3ac54c8428eef0dd076dfc1718
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2023-02-24 15:36:28 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2023-02-24 15:36:28 +0000

    nfsd: Fix a use after free when vnet prisons are deleted
    
    The Kasan tests show the nfsrvd_cleancache() results
    in a modify after free. I think this occurs because the
    nfsrv_cleanup() function gets executed after nfs_cleanup()
    which free's the nfsstatsv1_p.
    
    This patch makes them use the same subsystem and sets
    SI_ORDER_FIRST for nfs_cleanup(), so that it will be called
    after nfsrv_cleanup() via VNET_SYSUNINIT().
    
    The patch also sets nfsstatsv1_p NULL after free'ng it,
    so that a crash will result if it is used after free'ng.
    
    Tested by:      markj
    Reviewed by:    markj
    MFC after:      3 months
    Differential Revision:  https://reviews.freebsd.org/D38750
---
 sys/fs/nfs/nfs_commonport.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c
index 212b498e6328..be5fc688b7eb 100644
--- a/sys/fs/nfs/nfs_commonport.c
+++ b/sys/fs/nfs/nfs_commonport.c
@@ -885,7 +885,7 @@ nfs_vnetinit(const void *unused __unused)
 	mtx_init(&NFSD_VNET(nfsrv_nfsuserdsock).nr_mtx, "nfsuserd",
 	    NULL, MTX_DEF);
 }
-VNET_SYSINIT(nfs_vnetinit, SI_SUB_VNET_DONE, SI_ORDER_ANY,
+VNET_SYSINIT(nfs_vnetinit, SI_SUB_VNET_DONE, SI_ORDER_FIRST,
     nfs_vnetinit, NULL);
 
 static void
@@ -893,12 +893,14 @@ nfs_cleanup(void *unused __unused)
 {
 
 	mtx_destroy(&NFSD_VNET(nfsrv_nfsuserdsock).nr_mtx);
-	if (!IS_DEFAULT_VNET(curvnet))
+	if (!IS_DEFAULT_VNET(curvnet)) {
 		free(NFSD_VNET(nfsstatsv1_p), M_TEMP);
+		NFSD_VNET(nfsstatsv1_p) = NULL;
+	}
 	/* Clean out the name<-->id cache. */
 	nfsrv_cleanusergroup();
 }
-VNET_SYSUNINIT(nfs_cleanup, SI_SUB_VNET_DONE, SI_ORDER_ANY,
+VNET_SYSUNINIT(nfs_cleanup, SI_SUB_VNET_DONE, SI_ORDER_FIRST,
     nfs_cleanup, NULL);
 
 extern int (*nfsd_call_nfscommon)(struct thread *, struct nfssvc_args *);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202302241537.31OFbWAo034841>