From 1beb3e2b251df5b59d817d90831805ba7d44b7ff Mon Sep 17 00:00:00 2001 From: Ayush Ranjan Date: Fri, 10 Feb 2023 13:38:52 -0800 Subject: [PATCH] Check hard link target's mount compatibility before kernfs.Dentry cast. Again. 1da6444d05e9 commit mistakenly reverted commit 8373fb5db8c8. Make the same commit again. This time add a regression test to avoid such a thing from happening again. Reported-by: syzbot+05b6f8c23f6cd54deb2c@syzkaller.appspotmail.com Reported-by: syzbot+c12cc3a057f3b75eb3cf@syzkaller.appspotmail.com PiperOrigin-RevId: 508743552 --- pkg/sentry/fsimpl/kernfs/filesystem.go | 10 +++++----- test/syscalls/linux/link.cc | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/pkg/sentry/fsimpl/kernfs/filesystem.go b/pkg/sentry/fsimpl/kernfs/filesystem.go index 5eaa9a5c5..6eb7bbeba 100644 --- a/pkg/sentry/fsimpl/kernfs/filesystem.go +++ b/pkg/sentry/fsimpl/kernfs/filesystem.go @@ -362,8 +362,9 @@ func (fs *Filesystem) LinkAt(ctx context.Context, rp *vfs.ResolvingPath, vd vfs. return err } - parent.dirMu.Lock() - defer parent.dirMu.Unlock() + if rp.Mount() != vd.Mount() { + return linuxerr.EXDEV + } inode := vd.Dentry().Impl().(*Dentry).Inode() if inode.Mode().IsDir() { return linuxerr.EPERM @@ -371,6 +372,8 @@ func (fs *Filesystem) LinkAt(ctx context.Context, rp *vfs.ResolvingPath, vd vfs. if err := vfs.MayLink(rp.Credentials(), inode.Mode(), inode.UID(), inode.GID()); err != nil { return err } + parent.dirMu.Lock() + defer parent.dirMu.Unlock() pc := rp.Component() if err := checkCreateLocked(ctx, rp.Credentials(), pc, parent); err != nil { return err @@ -378,9 +381,6 @@ func (fs *Filesystem) LinkAt(ctx context.Context, rp *vfs.ResolvingPath, vd vfs. if rp.MustBeDir() { return linuxerr.ENOENT } - if rp.Mount() != vd.Mount() { - return linuxerr.EXDEV - } if err := rp.Mount().CheckBeginWrite(); err != nil { return err } diff --git a/test/syscalls/linux/link.cc b/test/syscalls/linux/link.cc index 8299b50d2..43e51667f 100644 --- a/test/syscalls/linux/link.cc +++ b/test/syscalls/linux/link.cc @@ -349,6 +349,12 @@ TEST(LinkTest, LinkatWithSymlinkFollow) { EXPECT_THAT(unlink(newname.c_str()), SyscallSucceeds()); } +TEST(LinkTest, KernfsAcrossFilesystem) { + auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + EXPECT_THAT(link(file.path().c_str(), "/sys/newfile"), + SyscallFailsWithErrno(::testing::AnyOf(EROFS, EXDEV))); +} + } // namespace } // namespace testing