git: c71535c29df0 - stable/13 - nfsd: Fix a use after free when vnet prisons are deleted
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 18 May 2023 23:12:12 UTC
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=c71535c29df0ed25b879b42b0ffe2fd5386fa94e commit c71535c29df0ed25b879b42b0ffe2fd5386fa94e Author: Rick Macklem <rmacklem@FreeBSD.org> AuthorDate: 2023-02-24 15:36:28 +0000 Commit: Rick Macklem <rmacklem@FreeBSD.org> CommitDate: 2023-05-18 23:10:58 +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. (cherry picked from commit 4036fcb8053adf3ac54c8428eef0dd076dfc1718) --- 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 e78edff964f9..7f64b3e978a3 100644 --- a/sys/fs/nfs/nfs_commonport.c +++ b/sys/fs/nfs/nfs_commonport.c @@ -886,7 +886,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 @@ -894,12 +894,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 *);