Check hard link target's mount compatibility before kernfs.Dentry cast. Again.

1da6444d05 commit mistakenly reverted commit 8373fb5db8. 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
This commit is contained in:
Ayush Ranjan
2023-02-10 13:42:00 -08:00
committed by gVisor bot
parent be42cbb51a
commit 1beb3e2b25
2 changed files with 11 additions and 5 deletions
+5 -5
View File
@@ -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
}
+6
View File
@@ -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