Commit 76166f5b authored by Sergey Volk's avatar Sergey Volk Committed by Commit Bot

[Chromecast] Skip AnonymousExecutable tests

On Chromecast both /dev/shm and /tmp are mounted with 'noexec' option,
which is ok, because Chromecast doesn't use NaCl. But this makes the
AnonymousExecutable tests fail. So modify the test logic to skip the
test if both /dev/shm and /tmp are mounted as 'noexec'

Bug: b/80553544
Change-Id: Ia0596153525b36c67d3f979b395c50534d1bee5c
Reviewed-on: https://chromium-review.googlesource.com/1101411Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Sergey Volk <servolk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567715}
parent 3a2072b3
......@@ -235,6 +235,15 @@ BASE_EXPORT bool SetPosixFilePermissions(const FilePath& path, int mode);
BASE_EXPORT bool ExecutableExistsInPath(Environment* env,
const FilePath::StringType& executable);
#if defined(OS_LINUX) || defined(OS_AIX)
// Determine if files under a given |path| can be mapped and then mprotect'd
// PROT_EXEC. This depends on the mount options used for |path|, which vary
// among different Linux distributions and possibly local configuration. It also
// depends on details of kernel--ChromeOS uses the noexec option for /dev/shm
// but its kernel allows mprotect with PROT_EXEC anyway.
BASE_EXPORT bool IsPathExecutable(const FilePath& path);
#endif // OS_LINUX || OS_AIX
#endif // OS_POSIX
// Returns true if the given directory is empty
......
......@@ -138,35 +138,6 @@ std::string TempFileName() {
#endif
}
#if defined(OS_LINUX) || defined(OS_AIX)
// Determine if /dev/shm files can be mapped and then mprotect'd PROT_EXEC.
// This depends on the mount options used for /dev/shm, which vary among
// different Linux distributions and possibly local configuration. It also
// depends on details of kernel--ChromeOS uses the noexec option for /dev/shm
// but its kernel allows mprotect with PROT_EXEC anyway.
bool DetermineDevShmExecutable() {
bool result = false;
FilePath path;
ScopedFD fd(
CreateAndOpenFdForTemporaryFileInDir(FilePath("/dev/shm"), &path));
if (fd.is_valid()) {
DeleteFile(path, false);
long sysconf_result = sysconf(_SC_PAGESIZE);
CHECK_GE(sysconf_result, 0);
size_t pagesize = static_cast<size_t>(sysconf_result);
CHECK_GE(sizeof(pagesize), sizeof(sysconf_result));
void* mapping = mmap(nullptr, pagesize, PROT_READ, MAP_SHARED, fd.get(), 0);
if (mapping != MAP_FAILED) {
if (mprotect(mapping, pagesize, PROT_READ | PROT_EXEC) == 0)
result = true;
munmap(mapping, pagesize);
}
}
return result;
}
#endif // defined(OS_LINUX) || defined(OS_AIX)
bool AdvanceEnumeratorWithStat(FileEnumerator* traversal,
FilePath* out_next_path,
struct stat* out_next_stat) {
......@@ -1016,7 +987,8 @@ bool GetShmemTempDir(bool executable, FilePath* path) {
#endif
bool use_dev_shm = true;
if (executable) {
static const bool s_dev_shm_executable = DetermineDevShmExecutable();
static const bool s_dev_shm_executable =
IsPathExecutable(FilePath("/dev/shm"));
use_dev_shm = s_dev_shm_executable;
}
if (use_dev_shm && !disable_dev_shm) {
......@@ -1083,4 +1055,28 @@ bool MoveUnsafe(const FilePath& from_path, const FilePath& to_path) {
} // namespace internal
#endif // !defined(OS_NACL_NONSFI)
#if defined(OS_LINUX) || defined(OS_AIX)
BASE_EXPORT bool IsPathExecutable(const FilePath& path) {
bool result = false;
FilePath tmp_file_path;
ScopedFD fd(CreateAndOpenFdForTemporaryFileInDir(path, &tmp_file_path));
if (fd.is_valid()) {
DeleteFile(tmp_file_path, false);
long sysconf_result = sysconf(_SC_PAGESIZE);
CHECK_GE(sysconf_result, 0);
size_t pagesize = static_cast<size_t>(sysconf_result);
CHECK_GE(sizeof(pagesize), sizeof(sysconf_result));
void* mapping = mmap(nullptr, pagesize, PROT_READ, MAP_SHARED, fd.get(), 0);
if (mapping != MAP_FAILED) {
if (mprotect(mapping, pagesize, PROT_READ | PROT_EXEC) == 0)
result = true;
munmap(mapping, pagesize);
}
}
return result;
}
#endif // defined(OS_LINUX) || defined(OS_AIX)
} // namespace base
......@@ -588,6 +588,15 @@ TEST_P(SharedMemoryTest, MapTwice) {
#if !defined(OS_IOS)
// Create a shared memory object, mmap it, and mprotect it to PROT_EXEC.
TEST_P(SharedMemoryTest, AnonymousExecutable) {
#if defined(OS_LINUX)
// On Chromecast both /dev/shm and /tmp are mounted with 'noexec' option,
// which makes this test fail. But Chromecast doesn't use NaCL so we don't
// need this.
if (!IsPathExecutable(FilePath("/dev/shm")) &&
!IsPathExecutable(FilePath("/tmp"))) {
return;
}
#endif // OS_LINUX
const uint32_t kTestSize = 1 << 16;
SharedMemory shared_memory;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment