summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNicolas Lacasse <nlacasse@google.com>2019-04-29 10:29:14 -0700
committerShentubot <shentubot@google.com>2019-04-29 10:30:24 -0700
commit2df64cd6d2c835ce5b37a8b9111d24ad382b5d3d (patch)
treec6a051741939cefb927ebb059ec893e5d510b618
parent66bca6fc221393c9553cbaa0486e07c8124e2477 (diff)
createAt should return all errors from FindInode except ENOENT.
Previously, createAt was eating all errors from FindInode except for EACCES and proceeding with the creation. This is incorrect, as FindInode can return many other errors (like ENAMETOOLONG) that should stop creation. This CL changes createAt to return all errors encountered except for ENOENT, which we can ignore because we are about to create the thing. PiperOrigin-RevId: 245773222 Change-Id: I1b317021de70f0550fb865506f6d8147d4aebc56
-rw-r--r--pkg/sentry/syscalls/linux/sys_file.go9
-rw-r--r--test/syscalls/linux/creat.cc11
2 files changed, 16 insertions, 4 deletions
diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go
index d2d351449..50151f7b6 100644
--- a/pkg/sentry/syscalls/linux/sys_file.go
+++ b/pkg/sentry/syscalls/linux/sys_file.go
@@ -347,10 +347,9 @@ func createAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint, mod
return syserror.ConvertIntr(err, kernel.ERESTARTSYS)
}
defer newFile.DecRef()
- case syserror.EACCES:
- // Permission denied while walking to the file.
- return err
- default:
+ case syserror.ENOENT:
+ // File does not exist. Proceed with creation.
+
// Do we have write permissions on the parent?
if err := d.Inode.CheckPermission(t, fs.PermMask{Write: true, Execute: true}); err != nil {
return err
@@ -365,6 +364,8 @@ func createAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint, mod
}
defer newFile.DecRef()
targetDirent = newFile.Dirent
+ default:
+ return err
}
// Success.
diff --git a/test/syscalls/linux/creat.cc b/test/syscalls/linux/creat.cc
index 72a016b4c..df2cc0d5c 100644
--- a/test/syscalls/linux/creat.cc
+++ b/test/syscalls/linux/creat.cc
@@ -51,6 +51,17 @@ TEST(CreatTest, CreatTruncatesExistingFile) {
EXPECT_EQ("", new_contents);
}
+TEST(CreatTest, CreatWithNameTooLong) {
+ // Start with a unique name, and pad it to NAME_MAX + 1;
+ std::string name = NewTempRelPath();
+ int padding = (NAME_MAX + 1) - name.size();
+ name.append(padding, 'x');
+ const std::string& path = JoinPath(GetAbsoluteTestTmpdir(), name);
+
+ // Creation should return ENAMETOOLONG.
+ ASSERT_THAT(creat(path.c_str(), kMode), SyscallFailsWithErrno(ENAMETOOLONG));
+}
+
} // namespace
} // namespace testing