Date: Tue, 11 Apr 2017 11:55:21 -0700 From: Maxim Sobolev <sobomax@freebsd.org> To: Kirk McKusick <mckusick@mckusick.com> Cc: FreeBSD Filesystems <freebsd-fs@freebsd.org> Subject: Re: mksnap_ffs(8) is not working while chrooted Message-ID: <CAH7qZfsqNgK1FtZbZ5gm55iCJTvb29AR0DqUNsW%2BEnEjzyUrcw@mail.gmail.com> In-Reply-To: <CAH7qZfsS61LEO1eR1T3uoYgiuOgLvnPZRpsScR--a3OnxLK3zw@mail.gmail.com> References: <CAH7qZfvO9AjiZM0FyHqRBzp-KN4u=7Pq4Y2xNhQ2W4t53rApTQ@mail.gmail.com> <201704111807.v3BI7PGM001952@chez.mckusick.com> <CAH7qZfsS61LEO1eR1T3uoYgiuOgLvnPZRpsScR--a3OnxLK3zw@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Kirk, yes, indeed, it works just fine if I chop out the chroot prefix manually here: [/builder.trunk/usr/src/sbin/mksnap_ffs]$ sudo chroot /builder.trunk sh # truncate -s 100m /tmp/fsimage # mdconfig -a -f /tmp/fsimage md0 # newfs /dev/md0 /dev/md0: 100.0MB (204800 sectors) block size 32768, fragment size 4096 using 4 cylinder groups of 25.03MB, 801 blks, 3328 inodes. super-block backups (for fsck_ffs -b #) at: 192, 51456, 102720, 153984 # mount /dev/md0 /mnt # /usr/src/sbin/mksnap_ffs/mksnap_ffs /mnt/mysnap # ls -l /mnt/mysnap -r--r----- 1 root operator 104857672 Apr 11 18:42 /mnt/mysnap # ^D [/builder.trunk/usr/src/sbin/mksnap_ffs]$ git diff diff --git a/sbin/mksnap_ffs/mksnap_ffs.c b/sbin/mksnap_ffs/mksnap_ffs.c index efd9c6b33..b1fba5e16 100644 --- a/sbin/mksnap_ffs/mksnap_ffs.c +++ b/sbin/mksnap_ffs/mksnap_ffs.c @@ -116,7 +116,7 @@ main(int argc, char **argv) iovlen = 0; build_iovec(&iov, &iovlen, "fstype", "ffs", 4); build_iovec(&iov, &iovlen, "from", snapname, (size_t)-1); - build_iovec(&iov, &iovlen, "fspath", stfsbuf.f_mntonname, (size_t)-1); + build_iovec(&iov, &iovlen, "fspath", stfsbuf.f_mntonname + 14, (size_t)-1); build_iovec(&iov, &iovlen, "errmsg", errmsg, sizeof(errmsg)); build_iovec(&iov, &iovlen, "update", NULL, 0); build_iovec(&iov, &iovlen, "snapshot", NULL, 0); So my point is that by making this scenario working OOB I don't think we would add any new security issue. This already works if you pass proper path into the nmount(2) and the mount path is inside chroot. In principle I can possibly do some clever trick on the userland only to strip offending prefix f_mntonname here component by component until we can locate the mount dir, but it's likely to be somewhat fuzzy and clearly not suitable for the basesrc repo. -Max On Tue, Apr 11, 2017 at 11:23 AM, Maxim Sobolev <sobomax@freebsd.org> wrote: > Kirk, what you are saying in not applying in our case. The whole FS is > mounted *inside* the chroot. The reason why we are trying to use mksnap_ffs > is to take a clean snapshot to make a compressed version of it without the > need to forcefully zero out free space. > > So it looks like the following: > > parent# chroot /mnt/chroot /bin/sh > chroot# truncate /tmp/diskimage > chroot# mdconfig -a -f /tmp/diskimage > md0 > chroot# newfs md0 > chroot# mount /dev/md0 /mnt > [...do stuff with /mnt...] > chroot# mksnap_ffs /mnt/snap > mksnap_ffs: No such file or directory > > Perhaps, to work around your concern is to add some flag for the statfs(1) > to normalize f_mntonname for use inside chroot then? I have not tested it > here, but I believe that if I'd strip "/mnt/chroot" prefix inside > mksnap_ffs(8) that would work in our scenario just fine. > > -Max > > On Tue, Apr 11, 2017 at 11:07 AM, Kirk McKusick <mckusick@mckusick.com> > wrote: > >> > From: Maxim Sobolev <sobomax@freebsd.org> >> > Date: Tue, 11 Apr 2017 10:40:58 -0700 >> > Subject: mksnap_ffs(8) is not working while chrooted >> > To: Kirk McKusick <mckusick@mckusick.com>, >> > FreeBSD Filesystems <freebsd-fs@freebsd.org> >> > >> > Hi Kirk et al, >> > >> > I've stumbled upon problem that it is impossible to use mksnap_ffs(8) >> while >> > in the chrooted environment. Other utilities that manipulate fs'es (i.e. >> > mount(8) / umount(8)) work just fine. Quick glance through the code >> shows >> > that the problem stems from the fact that mksnap_ffs uses f_mntonname >> > returned by the statfs(2) system call to fill fspath parameter for the >> > nmount call. And the statfs() returns f_mntonname path outside chroot. >> As >> > far as I can see, there are two options to address this issue. >> > >> > 1. Adjust statfs(2) system call to substract chroot prefix while >> > returning f_mntonname. Similar to what prison_enforce_statfs() function >> > does for jails. >> > >> > 2. Enhance nmount(2) to allow taking FSID in place of mount path to do >> > resolution using existing flag MNT_BYFSID and adjust mksnap_ffs to use >> that >> > instead. This is what umount(8) does to work around the problem. >> > >> > Which of two approaches would be preferred solution if any? The second >> one >> > seems a bit simpler to me. Please advise. Thanks! >> > >> > -Max >> >> It is not secure to allow mksnap_ffs(8) to work inside a jail. The issue >> is that mksnap_ffs takes a snapshot of the entire filesystem. Based on the >> way that snapshots work in FFS, it is not possible to snapshot only the >> part of the filesystem that is in the jail. Thus, if you take a snapshot >> of the entire filesystem and then mount it inside the jail, you will >> expose parts of the filesystem from outside of the jail to the jail. >> As such, you should only be able to snapshot a filesystem if it is >> entirely contained within the jail. >> >> If snapshots within jails are important to you, I recommend that you use >> ZFS which allows you to create per-jail filesystems which you can then >> snapshot. >> >> Kirk McKusick >> >> >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAH7qZfsqNgK1FtZbZ5gm55iCJTvb29AR0DqUNsW%2BEnEjzyUrcw>