diff options
-rw-r--r-- | pkg/sentry/fs/proc/uid_gid_map.go | 5 | ||||
-rw-r--r-- | test/syscalls/linux/proc_pid_uid_gid_map.cc | 17 |
2 files changed, 21 insertions, 1 deletions
diff --git a/pkg/sentry/fs/proc/uid_gid_map.go b/pkg/sentry/fs/proc/uid_gid_map.go index a52e0cb1f..0c68bbfc9 100644 --- a/pkg/sentry/fs/proc/uid_gid_map.go +++ b/pkg/sentry/fs/proc/uid_gid_map.go @@ -169,5 +169,8 @@ func (imfo *idMapFileOperations) Write(ctx context.Context, file *fs.File, src u if err != nil { return 0, err } - return int64(len(b)), nil + + // On success, Linux's kernel/user_namespace.c:map_write() always returns + // count, even if fewer bytes were used. + return int64(srclen), nil } diff --git a/test/syscalls/linux/proc_pid_uid_gid_map.cc b/test/syscalls/linux/proc_pid_uid_gid_map.cc index bf0f8b2bb..e6a5265fa 100644 --- a/test/syscalls/linux/proc_pid_uid_gid_map.cc +++ b/test/syscalls/linux/proc_pid_uid_gid_map.cc @@ -129,6 +129,23 @@ TEST_P(ProcSelfUidGidMapTest, IdentityMapOwnID) { IsPosixErrorOkAndHolds(0)); } +TEST_P(ProcSelfUidGidMapTest, TrailingNewlineAndNULIgnored) { + // This is identical to IdentityMapOwnID, except that a trailing newline, NUL, + // and an invalid (incomplete) map entry are appended to the valid entry. The + // newline should be accepted, and everything after the NUL should be ignored. + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanCreateUserNamespace())); + uint32_t id = CurrentID(); + std::string line = absl::StrCat(id, " ", id, " 1\n\0 4 3"); + EXPECT_THAT( + InNewUserNamespaceWithMapFD([&](int fd) { + DenySelfSetgroups(); + // The write should return the full size of the write, even though + // characters after the NUL were ignored. + TEST_PCHECK(write(fd, line.c_str(), line.size()) == line.size()); + }), + IsPosixErrorOkAndHolds(0)); +} + TEST_P(ProcSelfUidGidMapTest, NonIdentityMapOwnID) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanCreateUserNamespace())); SKIP_IF(ASSERT_NO_ERRNO_AND_VALUE(HaveSetIDCapability())); |