From 02c3d56956dc4c94a9076b6d7eb56d26534faa9c Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Mon, 27 Apr 2020 13:28:33 -0500 Subject: [PATCH] afs: Avoid touching CBRs after free Currently, we free our CBR structures in shutdown_vcache, but later on in shutdown_server, we call afs_FreeCBR on each one that's attached to a struct server. afs_FreeCBR doesn't actually free the memory; it just modifies some pointers to put the CBR on the free list. Since we do this after the underlying memory has been freed, it can cause a panic during shutdown since the structures are no longer valid. To avoid this, make the afs_FreeCBR calls inside shutdown_vcache, right before the memory is freed. Change-Id: I142126d6aa811762b6c234d05abdac3764dad887 Reviewed-on: https://gerrit.openafs.org/14165 Reviewed-by: Michael Meffie Reviewed-by: Benjamin Kaduk Tested-by: BuildBot --- src/afs/afs_init.c | 8 -------- src/afs/afs_vcache.c | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/afs/afs_init.c b/src/afs/afs_init.c index d32237e..4d1984c 100644 --- a/src/afs/afs_init.c +++ b/src/afs/afs_init.c @@ -746,7 +746,6 @@ static void shutdown_server(void) { int i; - struct afs_cbr *tcbrp, *tbrp; struct srvAddr *sa; for (i = 0; i < NSERVERS; i++) { @@ -764,13 +763,6 @@ shutdown_server(void) afs_ReleaseConns(sa->conns); } } - for (tcbrp = ts->cbrs; tcbrp; tcbrp = tbrp) { - /* - * Free all server's callback structs - */ - tbrp = tcbrp->next; - afs_FreeCBR(tcbrp); - } afs_osi_Free(ts, sizeof(struct server)); ts = next; } diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index 6ff81b9..670ad62 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -2978,6 +2978,9 @@ shutdown_vcache(void) { int i; struct afs_cbr *tsp; + struct afs_cbr *cbr, *cbr_next; + struct server *ts; + /* * XXX We may potentially miss some of the vcaches because if when * there are no free vcache entries and all the vcache entries are active @@ -3047,6 +3050,20 @@ shutdown_vcache(void) afs_vhashT[i] = 0; } } + + /* + * Remove any reference to CBRs in the server structs before we free the + * memory for our CBRs below. + */ + for (i = 0; i < NSERVERS; i++) { + for (ts = afs_servers[i]; ts; ts = ts->next) { + for (cbr = ts->cbrs; cbr; cbr = cbr_next) { + cbr_next = cbr->next; + afs_FreeCBR(cbr); + } + } + } + /* * Free any leftover callback queue */ -- 1.9.4