]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit - sys/ufs/ufs/ufs_lookup.c
Add a framework that tracks exclusive vnode lock generation count for UFS.
authorkib <kib@FreeBSD.org>
Sat, 14 Nov 2020 05:10:39 +0000 (05:10 +0000)
committerkib <kib@FreeBSD.org>
Sat, 14 Nov 2020 05:10:39 +0000 (05:10 +0000)
commit7d5679ae36bf19bfe61991fc2f557150d30a2719
treedb5f889276cdf2f3e629d4b5fe9567f089d5a989
parent6ab22cb426e8a6d7d37dfd30e8e95332b2e76b66
Add a framework that tracks exclusive vnode lock generation count for UFS.

This count is memoized together with the lookup metadata in directory
inode, and we assert that accesses to lookup metadata are done under
the same lock generation as they were stored.  Enabled under DIAGNOSTICS.

UFS saves additional data for parent dirent when doing lookup
(i_offset, i_count, i_endoff), and this data is used later by VOPs
operating on dirents.  If parent vnode exclusive lock is dropped and
re-acquired between lookup and the VOP call, we corrupt directories.

Framework asserts that corruption cannot occur that way, by tracking
vnode lock generation counter.  Updates to inode dirent members also
save the counter, while users compare current and saved counters
values.

Also, fix a case in ufs_lookup_ino() where i_offset and i_count could
be updated under shared lock.  It is not a bug on its own since dvp
i_offset results from such lookup cannot be used, but it causes false
positive in the checker.

In collaboration with: pho
Reviewed by: mckusick (previous version), markj
Tested by: markj (syzkaller), pho
Sponsored by: The FreeBSD Foundation
Differential revision: https://reviews.freebsd.org/D26136
sys/ufs/ffs/ffs_alloc.c
sys/ufs/ffs/ffs_softdep.c
sys/ufs/ffs/ffs_vfsops.c
sys/ufs/ffs/ffs_vnops.c
sys/ufs/ufs/inode.h
sys/ufs/ufs/ufs_lookup.c
sys/ufs/ufs/ufs_vnops.c