Bug 251342 - fs/unionfs: VOP_UNSET_TEXT without VOP_SET_TEXT leads to panic
Summary: fs/unionfs: VOP_UNSET_TEXT without VOP_SET_TEXT leads to panic
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: amd64 Any
: --- Affects Only Me
Assignee: freebsd-fs (Nobody)
URL:
Keywords: crash
Depends on:
Blocks:
 
Reported: 2020-11-24 11:02 UTC by Michael Zhilin
Modified: 2023-01-09 15:02 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Zhilin freebsd_committer freebsd_triage 2020-11-24 11:02:51 UTC
Hi,

Here is kernel panic on unionfs. 
During removal of vm map, kernel tries to unset text of vnode without previous setting text of vnode.

VNASSERT failed: error_ == 0 not true at /usr/src/sys/vm/vm_map.c:601 (vm_map_entry_set_vnode_text)
0xfffff8000844e988: type VREG
    usecount 1, writecount 0, refcount 2 seqc users 0
    hold count flags ()
    flags (VIRF_PGREAD)
    v_object 0xfffff80008401528 ref 4 pages 6 cleanbuf 0 dirtybuf 0
    lock type tmpfs: SHARED (count 1)
tag VT_TMPFS, tmpfs_node 0xfffff800084549a0, flags 0x0, links 1
	mode 0555, owner 0, group 0, size 20912, status 0x0

panic: VOP_UNSET_TEXT returned 22
time = 1606214918
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0015e718d0
vpanic() at vpanic+0x182/frame 0xfffffe0015e71920
panic() at panic+0x43/frame 0xfffffe0015e71980
vm_map_entry_set_vnode_text() at vm_map_entry_set_vnode_text+0x267/frame 0xfffffe0015e719c0
vm_map_process_deferred() at vm_map_process_deferred+0x9e/frame 0xfffffe0015e719e0
vm_map_remove() at vm_map_remove+0xc9/frame 0xfffffe0015e71a10
vmspace_exit() at vmspace_exit+0xa9/frame 0xfffffe0015e71a40
exit1() at exit1+0x542/frame 0xfffffe0015e71ab0
sys_sys_exit() at sys_sys_exit+0xd/frame 0xfffffe0015e71ac0
amd64_syscall() at amd64_syscall+0x12e/frame 0xfffffe0015e71bf0
fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe0015e71bf0
--- syscall (1, FreeBSD ELF64, sys_sys_exit), rip = 0x800387aca, rsp = 0x7fffffffe578, rbp = 0x7fffffffe590 ---
KDB: enter: panic
[ thread pid 680 tid 100071 ]
Stopped at      kdb_enter+0x37: movq    $0,0x10adc26(%rip)

Test case to reproduce it in vm-bhyve:

vm create unionfstest
vm iso https://download.freebsd.org/ftp/snapshots/ISO-IMAGES/13.0/FreeBSD-13.0-CURRENT-amd64-20201119-f2ea0734875-bootonly.iso
vm install unionfstest FreeBSD-13.0-CURRENT-amd64-20201119-f2ea0734875-bootonly.iso
vm console unionfstest

Inside VM (plz choose live cd or shell):

mkdir /tmp/var
mount -t unionfs -o below /var /tmp/var
cd /tmp/var
cp /bin/date /tmp/var
/tmp/var/date
Comment 1 commit-hook freebsd_committer freebsd_triage 2022-01-03 03:46:24 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=9e891d43f586e91541bd61fb12550de296d76fd9

commit 9e891d43f586e91541bd61fb12550de296d76fd9
Author:     Jason A. Harmening <jah@FreeBSD.org>
AuthorDate: 2021-12-21 23:51:51 +0000
Commit:     Jason A. Harmening <jah@FreeBSD.org>
CommitDate: 2022-01-03 03:52:58 +0000

    unionfs: implement VOP_SET_TEXT/VOP_UNSET_TEXT

    The implementation simply passes the text ref to the appropriate
    underlying vnode.  Without this, the default [un]set_text
    implementation will only manage the text ref on the unionfs vnode,
    causing it to be out of sync with the underlying filesystems and
    potentially allowing corruption of executable file contents.
    On INVARIANTS kernels, it also readily produces a panic on process
    termination because the VM object representing the executable mapping
    is backed by the underlying vnode, not the unionfs vnode.

    PR:     251342
    Reviewed by:    kib
    Differential Revision: https://reviews.freebsd.org/D33611

 sys/fs/unionfs/union_vnops.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
Comment 2 Michael Zhilin freebsd_committer freebsd_triage 2022-10-17 09:02:47 UTC
As reporter, I confirms that fix works fine since 14.0, for validation i use only test case.

Many thanks to jah@.

Closed.
Comment 3 Ed Maste freebsd_committer freebsd_triage 2022-10-31 12:50:57 UTC
Any reason this shouldn't be MFC'd?
Comment 4 commit-hook freebsd_committer freebsd_triage 2023-01-09 15:02:08 UTC
A commit in branch stable/13 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=04f8674aa7486ec2d73d60c2247fe5e33b5399c5

commit 04f8674aa7486ec2d73d60c2247fe5e33b5399c5
Author:     Jason A. Harmening <jah@FreeBSD.org>
AuthorDate: 2021-12-21 23:51:51 +0000
Commit:     Ed Maste <emaste@FreeBSD.org>
CommitDate: 2023-01-09 02:31:15 +0000

    unionfs: implement VOP_SET_TEXT/VOP_UNSET_TEXT

    The implementation simply passes the text ref to the appropriate
    underlying vnode.  Without this, the default [un]set_text
    implementation will only manage the text ref on the unionfs vnode,
    causing it to be out of sync with the underlying filesystems and
    potentially allowing corruption of executable file contents.
    On INVARIANTS kernels, it also readily produces a panic on process
    termination because the VM object representing the executable mapping
    is backed by the underlying vnode, not the unionfs vnode.

    PR:     251342
    Reviewed by:    kib
    Differential Revision: https://reviews.freebsd.org/D33611

    (cherry picked from commit 9e891d43f586e91541bd61fb12550de296d76fd9)

 sys/fs/unionfs/union_vnops.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)