Bug 263662 - [fusefs] kernel panics if fuse daemon returns parent's i-number in FUSE_CREATE
Summary: [fusefs] kernel panics if fuse daemon returns parent's i-number in FUSE_CREATE
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: Unspecified
Hardware: Any Any
: --- Affects Some People
Assignee: Alan Somers
URL: https://reviews.freebsd.org/D35128
Keywords:
Depends on:
Blocks:
 
Reported: 2022-04-29 17:52 UTC by Robert Morris
Modified: 2022-08-20 02:57 UTC (History)
3 users (show)

See Also:
asomers: mfc-stable13+
asomers: mfc-stable12-


Attachments
fuse daemon that causes a panic by returning parent dir's i-number for FUSE_CREATE (17.01 KB, text/plain)
2022-04-29 17:52 UTC, Robert Morris
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Robert Morris 2022-04-29 17:52:22 UTC
Created attachment 233588 [details]
fuse daemon that causes a panic by returning parent dir's i-number for FUSE_CREATE

If a fuse daemon returns the parent directory's i-number for a new
file in FUSE_CREATE, the kernel notices that it is trying to acquire a
lock it already holds, and panics.

I've attached a demo:

# uname -a
FreeBSD  14.0-CURRENT FreeBSD 14.0-CURRENT #1 main-n250917-440e36e68279: Fri Apr 29 07:33:58 EDT 2022     rtm@xxx:/usr/obj/usr/rtm/symbsd/src/riscv.riscv64/sys/RTM2  riscv
# pkg install fusefs-libs
# cc -I/usr/local/include/fuse -o futo1a futo1a.c -L/usr/local/lib -lfuse
# ./futo1a
...
panic: lockmgr_xlock_hard: recursing on non recursive lockmgr 0xffffffd0012e5cb0 @ /usr/rtm/symbsd/src/sys/kern/vfs_subr.c:3023                                 
cpuid = 0
time = 1649872295
KDB: stack backtrace:
db_trace_self() at db_trace_self
db_trace_self_wrapper() at db_trace_self_wrapper+0x38
kdb_backtrace() at kdb_backtrace+0x2c
vpanic() at vpanic+0x16e
panic() at panic+0x2a
lockmgr_xlock_hard() at lockmgr_xlock_hard+0xb4
lockmgr_lock_flags() at lockmgr_lock_flags+0x14e
vop_stdlock() at vop_stdlock+0x1c
VOP_LOCK1_APV() at VOP_LOCK1_APV+0x32
VOP_LOCK1() at VOP_LOCK1+0x2e
_vn_lock() at _vn_lock+0x30
vget_finish() at vget_finish+0x48
vfs_hash_get() at vfs_hash_get+0xb6
fuse_vnode_alloc() at fuse_vnode_alloc+0x5c
fuse_vnode_get() at fuse_vnode_get+0x48
fuse_vnop_create() at fuse_vnop_create+0x300
VOP_CREATE_APV() at VOP_CREATE_APV+0x3a
VOP_CREATE() at VOP_CREATE+0x2e
vn_open_cred() at vn_open_cred+0x21e
kern_openat() at kern_openat+0x16a
sys_openat() at sys_openat+0x32
syscallenter() at syscallenter+0xf4
ecall_handler() at ecall_handler+0x18
do_trap_user() at do_trap_user+0xea
cpu_exception_handler_user() at cpu_exception_handler_user+0x72
--- exception 8, tval = 0xd12b67000
KDB: enter: panic
[ thread pid 35 tid 100051 ]
Stopped at      breakpoint+0xa: c.ldsp  s0,0(sp)
db>
Comment 1 commit-hook freebsd_committer freebsd_triage 2022-05-12 20:33:59 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=0bef4927ea858bb18b6f679bc0a36cff264dc842

commit 0bef4927ea858bb18b6f679bc0a36cff264dc842
Author:     Alan Somers <asomers@FreeBSD.org>
AuthorDate: 2022-05-04 23:36:17 +0000
Commit:     Alan Somers <asomers@FreeBSD.org>
CommitDate: 2022-05-12 20:32:26 +0000

    fusefs: handle evil servers that return illegal inode numbers

    * If during FUSE_CREATE, FUSE_MKDIR, etc the server returns the same
      inode number for the new file as for its parent directory, reject it.
      Previously this would triggers a recurse-on-non-recursive lock panic.

    * If during FUSE_LINK the server returns a different inode number for
      the new name as for the old one, reject it.  Obviously, that can't be
      a hard link.

    * If during FUSE_LOOKUP the server returns the same inode number for the
      new file as for its parent directory, reject it.  Nothing good can
      come of this.

    PR:             263662
    Reported by:    Robert Morris <rtm@lcs.mit.edu>
    MFC after:      2 weeks
    Reviewed by:    pfg
    Differential Revision: https://reviews.freebsd.org/D35128

 sys/fs/fuse/fuse_ipc.h         |  1 +
 sys/fs/fuse/fuse_node.c        |  6 +++++
 sys/fs/fuse/fuse_vnops.c       | 27 ++++++++++++++++++---
 tests/sys/fs/fusefs/create.cc  | 41 ++++++++++++++++++++++++++++++++
 tests/sys/fs/fusefs/link.cc    | 47 +++++++++++++++++++++++++++++++++++++
 tests/sys/fs/fusefs/lookup.cc  | 31 ++++++++++++++++++++++++
 tests/sys/fs/fusefs/mkdir.cc   | 53 ++++++++++++++++++++++++++++++++++++++++++
 tests/sys/fs/fusefs/mknod.cc   | 32 +++++++++++++++++++++++++
 tests/sys/fs/fusefs/symlink.cc | 22 ++++++++++++++++++
 9 files changed, 257 insertions(+), 3 deletions(-)
Comment 2 commit-hook freebsd_committer freebsd_triage 2022-06-18 14:17:33 UTC
A commit in branch stable/13 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=1f44d1861a0189130f8fb419ebcb1c5b1e627349

commit 1f44d1861a0189130f8fb419ebcb1c5b1e627349
Author:     Alan Somers <asomers@FreeBSD.org>
AuthorDate: 2022-05-04 23:36:17 +0000
Commit:     Alan Somers <asomers@FreeBSD.org>
CommitDate: 2022-06-18 14:16:20 +0000

    fusefs: handle evil servers that return illegal inode numbers

    * If during FUSE_CREATE, FUSE_MKDIR, etc the server returns the same
      inode number for the new file as for its parent directory, reject it.
      Previously this would triggers a recurse-on-non-recursive lock panic.

    * If during FUSE_LINK the server returns a different inode number for
      the new name as for the old one, reject it.  Obviously, that can't be
      a hard link.

    * If during FUSE_LOOKUP the server returns the same inode number for the
      new file as for its parent directory, reject it.  Nothing good can
      come of this.

    PR:             263662
    Reported by:    Robert Morris <rtm@lcs.mit.edu>
    Reviewed by:    pfg
    Differential Revision: https://reviews.freebsd.org/D35128

    (cherry picked from commit 0bef4927ea858bb18b6f679bc0a36cff264dc842)

 sys/fs/fuse/fuse_ipc.h         |  1 +
 sys/fs/fuse/fuse_node.c        |  6 +++++
 sys/fs/fuse/fuse_vnops.c       | 27 ++++++++++++++++++---
 tests/sys/fs/fusefs/create.cc  | 41 ++++++++++++++++++++++++++++++++
 tests/sys/fs/fusefs/link.cc    | 47 +++++++++++++++++++++++++++++++++++++
 tests/sys/fs/fusefs/lookup.cc  | 31 ++++++++++++++++++++++++
 tests/sys/fs/fusefs/mkdir.cc   | 53 ++++++++++++++++++++++++++++++++++++++++++
 tests/sys/fs/fusefs/mknod.cc   | 32 +++++++++++++++++++++++++
 tests/sys/fs/fusefs/symlink.cc | 22 ++++++++++++++++++
 9 files changed, 257 insertions(+), 3 deletions(-)
Comment 3 commit-hook freebsd_committer freebsd_triage 2022-08-20 02:57:44 UTC
A commit in branch stable/12 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=93891ed2f794ba871f8cae5cc5fc04abced2d157

commit 93891ed2f794ba871f8cae5cc5fc04abced2d157
Author:     Alan Somers <asomers@FreeBSD.org>
AuthorDate: 2022-05-03 22:53:20 +0000
Commit:     Alan Somers <asomers@FreeBSD.org>
CommitDate: 2022-08-20 02:33:08 +0000

    fusefs: make the mknod.cc tests a bit more general.

    Reviewed by:    pfg

    (cherry picked from commit 8b582b16402102df10a715c626e212bbbc8e9d7c)

    fusefs: handle evil servers that return illegal inode numbers

    * If during FUSE_CREATE, FUSE_MKDIR, etc the server returns the same
      inode number for the new file as for its parent directory, reject it.
      Previously this would triggers a recurse-on-non-recursive lock panic.

    * If during FUSE_LINK the server returns a different inode number for
      the new name as for the old one, reject it.  Obviously, that can't be
      a hard link.

    * If during FUSE_LOOKUP the server returns the same inode number for the
      new file as for its parent directory, reject it.  Nothing good can
      come of this.

    PR:             263662
    Reported by:    Robert Morris <rtm@lcs.mit.edu>
    Reviewed by:    pfg
    Differential Revision: https://reviews.freebsd.org/D35128

    (cherry picked from commit 0bef4927ea858bb18b6f679bc0a36cff264dc842)

 sys/fs/fuse/fuse_ipc.h         |   1 +
 sys/fs/fuse/fuse_node.c        |   6 +++
 sys/fs/fuse/fuse_vnops.c       |  27 ++++++++--
 tests/sys/fs/fusefs/create.cc  |  41 +++++++++++++++
 tests/sys/fs/fusefs/link.cc    |  47 +++++++++++++++++
 tests/sys/fs/fusefs/lookup.cc  |  31 +++++++++++
 tests/sys/fs/fusefs/mkdir.cc   |  53 +++++++++++++++++++
 tests/sys/fs/fusefs/mknod.cc   | 117 ++++++++++++++++++++++++++++++++---------
 tests/sys/fs/fusefs/symlink.cc |  22 ++++++++
 9 files changed, 317 insertions(+), 28 deletions(-)