summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pkg/sentry/syscalls/linux/sys_file.go9
-rw-r--r--test/syscalls/linux/symlink.cc15
2 files changed, 21 insertions, 3 deletions
diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go
index eb6f5648f..40722abc2 100644
--- a/pkg/sentry/syscalls/linux/sys_file.go
+++ b/pkg/sentry/syscalls/linux/sys_file.go
@@ -353,7 +353,8 @@ func createAt(t *kernel.Task, dirFD int32, addr usermem.Addr, flags uint, mode l
// No more resolution necessary.
defer resolved.DecRef()
break
- } else if err != fs.ErrResolveViaReadlink {
+ }
+ if err != fs.ErrResolveViaReadlink {
return err
}
@@ -363,15 +364,17 @@ func createAt(t *kernel.Task, dirFD int32, addr usermem.Addr, flags uint, mode l
}
// Resolve the symlink to a path via Readlink.
- path, err := found.Inode.Readlink(t)
+ var path string
+ path, err = found.Inode.Readlink(t)
if err != nil {
break
}
remainingTraversals--
// Get the new parent from the target path.
+ var newParent *fs.Dirent
newParentPath, newName := fs.SplitLast(path)
- newParent, err := t.MountNamespace().FindInode(t, root, parent, newParentPath, &remainingTraversals)
+ newParent, err = t.MountNamespace().FindInode(t, root, parent, newParentPath, &remainingTraversals)
if err != nil {
break
}
diff --git a/test/syscalls/linux/symlink.cc b/test/syscalls/linux/symlink.cc
index 69650a1d3..b249ff91f 100644
--- a/test/syscalls/linux/symlink.cc
+++ b/test/syscalls/linux/symlink.cc
@@ -325,6 +325,21 @@ TEST_P(ParamSymlinkTest, CreateExistingSelfLink) {
ASSERT_THAT(unlink(linkpath.c_str()), SyscallSucceeds());
}
+// Test that opening a file that is a symlink to its parent directory fails
+// with ELOOP.
+TEST_P(ParamSymlinkTest, CreateExistingParentLink) {
+ ASSERT_THAT(chdir(GetAbsoluteTestTmpdir().c_str()), SyscallSucceeds());
+
+ const std::string linkpath = GetParam();
+ const std::string target = JoinPath(linkpath, "child");
+ ASSERT_THAT(symlink(target.c_str(), linkpath.c_str()), SyscallSucceeds());
+
+ EXPECT_THAT(open(linkpath.c_str(), O_CREAT, 0666),
+ SyscallFailsWithErrno(ELOOP));
+
+ ASSERT_THAT(unlink(linkpath.c_str()), SyscallSucceeds());
+}
+
// Test that opening an existing symlink with O_CREAT|O_EXCL will fail with
// EEXIST.
TEST_P(ParamSymlinkTest, OpenLinkExclFails) {