diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2024-04-10 05:50:18 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-05-30 10:44:24 +0300 |
commit | 501cd8fabf621d10bd4893e37f6ce6c20523c8ca (patch) | |
tree | 5d19ee90afffc4d3f62f90d0e7631d5f1ce911fc /fs/gfs2/incore.h | |
parent | 666a7a9b6ddafe7802ae6a53f513d17e790056a0 (diff) | |
download | linux-501cd8fabf621d10bd4893e37f6ce6c20523c8ca.tar.xz |
gfs2: Fix potential glock use-after-free on unmount
[ Upstream commit d98779e687726d8f8860f1c54b5687eec5f63a73 ]
When a DLM lockspace is released and there ares still locks in that
lockspace, DLM will unlock those locks automatically. Commit
fb6791d100d1b started exploiting this behavior to speed up filesystem
unmount: gfs2 would simply free glocks it didn't want to unlock and then
release the lockspace. This didn't take the bast callbacks for
asynchronous lock contention notifications into account, which remain
active until until a lock is unlocked or its lockspace is released.
To prevent those callbacks from accessing deallocated objects, put the
glocks that should not be unlocked on the sd_dead_glocks list, release
the lockspace, and only then free those glocks.
As an additional measure, ignore unexpected ast and bast callbacks if
the receiving glock is dead.
Fixes: fb6791d100d1b ("GFS2: skip dlm_unlock calls in unmount")
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Cc: David Teigland <teigland@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'fs/gfs2/incore.h')
-rw-r--r-- | fs/gfs2/incore.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 95a334d64da2..60abd7050c99 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -838,6 +838,7 @@ struct gfs2_sbd { /* For quiescing the filesystem */ struct gfs2_holder sd_freeze_gh; struct mutex sd_freeze_mutex; + struct list_head sd_dead_glocks; char sd_fsname[GFS2_FSNAME_LEN + 3 * sizeof(int) + 2]; char sd_table_name[GFS2_FSNAME_LEN]; |