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
This commit is contained in:
parent
70960bb86a
commit
4036fcb805
@ -885,7 +885,7 @@ nfs_vnetinit(const void *unused __unused)
|
|||||||
mtx_init(&NFSD_VNET(nfsrv_nfsuserdsock).nr_mtx, "nfsuserd",
|
mtx_init(&NFSD_VNET(nfsrv_nfsuserdsock).nr_mtx, "nfsuserd",
|
||||||
NULL, MTX_DEF);
|
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);
|
nfs_vnetinit, NULL);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -893,12 +893,14 @@ nfs_cleanup(void *unused __unused)
|
|||||||
{
|
{
|
||||||
|
|
||||||
mtx_destroy(&NFSD_VNET(nfsrv_nfsuserdsock).nr_mtx);
|
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);
|
free(NFSD_VNET(nfsstatsv1_p), M_TEMP);
|
||||||
|
NFSD_VNET(nfsstatsv1_p) = NULL;
|
||||||
|
}
|
||||||
/* Clean out the name<-->id cache. */
|
/* Clean out the name<-->id cache. */
|
||||||
nfsrv_cleanusergroup();
|
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);
|
nfs_cleanup, NULL);
|
||||||
|
|
||||||
extern int (*nfsd_call_nfscommon)(struct thread *, struct nfssvc_args *);
|
extern int (*nfsd_call_nfscommon)(struct thread *, struct nfssvc_args *);
|
||||||
|
Loading…
Reference in New Issue
Block a user