ffs_snapshot() assumes that the file system is already mounted, since it dereferences mp->mnt_data (via VFSTOUFS(mp)). That's the case if a snapshot is asked for with the MNT_UPDATE flag. But if a program calls nmount() with "snapshot" but no "update", ffs_snapshot() will be called with a NULL mnt_data. You can see the crash by commenting out the "update" line in mksnap_ffs.c, or by running this as root: #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/param.h> #include <sys/mount.h> #include <sys/uio.h> int main() { struct iovec iov[10]; iov[0].iov_base = "fstype"; iov[0].iov_len = 7; iov[1].iov_base = "ffs"; iov[1].iov_len = 4; iov[2].iov_base = "fspath"; iov[2].iov_len = 7; iov[3].iov_base = "/"; iov[3].iov_len = 2; iov[4].iov_base = "snapshot"; iov[4].iov_len = 9; iov[5].iov_base = ""; iov[5].iov_len = 1; iov[6].iov_base = "from"; iov[6].iov_len = 5; iov[7].iov_base = "x"; iov[7].iov_len = 2; nmount(iov, 8, 0); } panic: Fatal page fault at 0xffffffc0004d94f2: 0x00000000000038 panic() at panic+0x2a page_fault_handler() at page_fault_handler+0x1a4 do_trap_supervisor() at do_trap_supervisor+0x76 cpu_exception_handler_supervisor() at cpu_exception_handler_supervisor+0x70 --- exception 13, tval = 0x38 ffs_snapshot() at ffs_snapshot+0x52 ffs_mount() at ffs_mount+0x372 vfs_domount_first() at vfs_domount_first+0x18c vfs_domount() at vfs_domount+0x208 vfs_donmount() at vfs_donmount+0x742 sys_nmount() at sys_nmount+0x5e syscallenter() at syscallenter+0xec ecall_handler() at ecall_handler+0x18 do_trap_user() at do_trap_user+0xea cpu_exception_handler_user() at cpu_exception_handler_user+0x72
Created attachment 236873 [details] proposed fix See attached proposed fix.
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=27d673fbbb79b1b829484ec127da59b45f623ebd commit 27d673fbbb79b1b829484ec127da59b45f623ebd Author: Kirk McKusick <mckusick@FreeBSD.org> AuthorDate: 2022-09-27 15:57:30 +0000 Commit: Kirk McKusick <mckusick@FreeBSD.org> CommitDate: 2022-09-27 15:58:10 +0000 When taking a snapshot on a UFS/FFS filesystem, it must be mounted. The "update" mount option must be specified when the "snapshot" mount option is used. Return EINVAL if the "snapshot" option is specified without the "update" option also requested. Reported by: Robert Morris Reviewed by: kib PR: 265362 MFC after: 2 weeks Sponsored by: The FreeBSD Foundation sys/ufs/ffs/ffs_vfsops.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
Will MFC to 13 before closing.
A commit in branch stable/13 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=0ae91878cc451ce5d45bbec815db830e0bc4c591 commit 0ae91878cc451ce5d45bbec815db830e0bc4c591 Author: Kirk McKusick <mckusick@FreeBSD.org> AuthorDate: 2022-09-27 15:57:30 +0000 Commit: Kirk McKusick <mckusick@FreeBSD.org> CommitDate: 2022-10-13 15:43:41 +0000 When taking a snapshot on a UFS/FFS filesystem, it must be mounted. PR: 265362 Sponsored by: The FreeBSD Foundation (cherry picked from commit 27d673fbbb79b1b829484ec127da59b45f623ebd) sys/ufs/ffs/ffs_vfsops.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
Now MFC'ed to 13, so close bug.