On Mon, Dec 02, 2024 at 06:30:41PM +0100, Alexander Bluhm wrote:
> On Mon, Dec 02, 2024 at 05:22:23PM +0100, Alexander Bluhm wrote:
> > panic: Data modified on freelist: word 11 of object 0xd7632800 size 0x270
> > previous type mount (0xdead410f != 0xdead4110)
>
> It looks like the struct mount mnt_lock rwl_readers was derecemented
> after free. rwl_readers = 3735896335 = 0xdead410f
>
> This happens in vfs_busy() with RW_READ. New rw_do_enter_read()
> function added call to rw_dec(&rwl->rwl_readers) there.
>
> I have the impression that the reimplementation of rw-lock makes
> the problem visible. Accessing struct mount after sleep is
> questionalble. Does anything prevent a file system unount while
> sleeping in vfs_busy()?
New implementation of rw-locks is wrong.
vfs_lookup() checks the existance of dp->v_mountedhere
each time before vfs_busy() is called.
while (dp->v_type == VDIR && (mp = dp->v_mountedhere) &&
(cnp->cn_flags & NOCROSSMOUNT) == 0) {
if (vfs_busy(mp, VB_READ|VB_WAIT))
continue;
vfs_busy() calls rw_enter() with RW_READ and RW_SLEEPFAIL.
Old rw_enter() did
error = sleep_finish(0, do_sleep);
...
if (flags & RW_SLEEPFAIL)
return (EAGAIN);
New rw_do_enter_read() does
error = sleep_finish(RW_SLEEP_TMO,
atomic_load_int(&rwl->rwl_waiters) > 0 ||
ISSET(atomic_load_long(&rwl->rwl_owner), RWLOCK_WRLOCK));
...
if (ISSET(flags, RW_SLEEPFAIL)) {
error = EAGAIN;
goto fail;
}
...
fail:
rw_dec(&rwl->rwl_readers);
return (error);
After sleep_finish() and RW_SLEEPFAIL there is no guarantee that
rwl is still valid memory. This is a use-after-free in rw_do_enter_read().
bluhm