// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/memory/shared_memory.h"

#include <memory>

#include "starboard/types.h"

#include "starboard/memory.h"

#include "base/atomicops.h"
#include "base/base_switches.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/shared_memory_handle.h"
#include "base/process/kill.h"
#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/sys_info.h"
#include "base/test/multiprocess_test.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"

#if defined(OS_ANDROID)
#include "base/callback.h"
#endif

#if defined(OS_POSIX)
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#endif

#if defined(OS_LINUX)
#include <sys/syscall.h>
#endif

#if defined(OS_WIN)
#include "base/win/scoped_handle.h"
#endif

#if defined(OS_FUCHSIA)
#include <lib/zx/vmar.h>
#include <lib/zx/vmo.h>
#endif

namespace base {

namespace {

#if !defined(OS_MACOSX) && !defined(OS_FUCHSIA)
// Each thread will open the shared memory.  Each thread will take a different 4
// byte int pointer, and keep changing it, with some small pauses in between.
// Verify that each thread's value in the shared memory is always correct.
class MultipleThreadMain : public PlatformThread::Delegate {
 public:
  explicit MultipleThreadMain(int16_t id) : id_(id) {}
  ~MultipleThreadMain() override = default;

  static void CleanUp() {
    SharedMemory memory;
    memory.Delete(s_test_name_);
  }

  // PlatformThread::Delegate interface.
  void ThreadMain() override {
    const uint32_t kDataSize = 1024;
    SharedMemory memory;
    bool rv = memory.CreateNamedDeprecated(s_test_name_, true, kDataSize);
    EXPECT_TRUE(rv);
    rv = memory.Map(kDataSize);
    EXPECT_TRUE(rv);
    int* ptr = static_cast<int*>(memory.memory()) + id_;
    EXPECT_EQ(0, *ptr);

    for (int idx = 0; idx < 100; idx++) {
      *ptr = idx;
      PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));
      EXPECT_EQ(*ptr, idx);
    }
    // Reset back to 0 for the next test that uses the same name.
    *ptr = 0;

    memory.Close();
  }

 private:
  int16_t id_;

  static const char s_test_name_[];

  DISALLOW_COPY_AND_ASSIGN(MultipleThreadMain);
};

const char MultipleThreadMain::s_test_name_[] =
    "SharedMemoryOpenThreadTest";
#endif  // !defined(OS_MACOSX) && !defined(OS_FUCHSIA)

enum class Mode {
  Default,
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
  DisableDevShm = 1,
#endif
};

class SharedMemoryTest : public ::testing::TestWithParam<Mode> {
 public:
  void SetUp() override {
    switch (GetParam()) {
      case Mode::Default:
        break;
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
      case Mode::DisableDevShm:
        CommandLine* cmdline = CommandLine::ForCurrentProcess();
        cmdline->AppendSwitch(switches::kDisableDevShmUsage);
        break;
#endif  // defined(OS_LINUX) && !defined(OS_CHROMEOS)
    }
  }
};

}  // namespace

// Android/Mac/Fuchsia doesn't support SharedMemory::Open/Delete/
// CreateNamedDeprecated(openExisting=true)
#if !defined(OS_ANDROID) && !defined(OS_MACOSX) && !defined(OS_FUCHSIA)

TEST_P(SharedMemoryTest, OpenClose) {
  const uint32_t kDataSize = 1024;
  std::string test_name = "SharedMemoryOpenCloseTest";

  // Open two handles to a memory segment, confirm that they are mapped
  // separately yet point to the same space.
  SharedMemory memory1;
  bool rv = memory1.Delete(test_name);
  EXPECT_TRUE(rv);
  rv = memory1.Delete(test_name);
  EXPECT_TRUE(rv);
  rv = memory1.Open(test_name, false);
  EXPECT_FALSE(rv);
  rv = memory1.CreateNamedDeprecated(test_name, false, kDataSize);
  EXPECT_TRUE(rv);
  rv = memory1.Map(kDataSize);
  EXPECT_TRUE(rv);
  SharedMemory memory2;
  rv = memory2.Open(test_name, false);
  EXPECT_TRUE(rv);
  rv = memory2.Map(kDataSize);
  EXPECT_TRUE(rv);
  EXPECT_NE(memory1.memory(), memory2.memory());  // Compare the pointers.

  // Make sure we don't segfault. (it actually happened!)
  ASSERT_NE(memory1.memory(), static_cast<void*>(nullptr));
  ASSERT_NE(memory2.memory(), static_cast<void*>(nullptr));

  // Write data to the first memory segment, verify contents of second.
  memset(memory1.memory(), '1', kDataSize);
  EXPECT_EQ(memcmp(memory1.memory(), memory2.memory(), kDataSize), 0);

  // Close the first memory segment, and verify the second has the right data.
  memory1.Close();
  char* start_ptr = static_cast<char*>(memory2.memory());
  char* end_ptr = start_ptr + kDataSize;
  for (char* ptr = start_ptr; ptr < end_ptr; ptr++)
    EXPECT_EQ(*ptr, '1');

  // Close the second memory segment.
  memory2.Close();

  rv = memory1.Delete(test_name);
  EXPECT_TRUE(rv);
  rv = memory2.Delete(test_name);
  EXPECT_TRUE(rv);
}

TEST_P(SharedMemoryTest, OpenExclusive) {
  const uint32_t kDataSize = 1024;
  const uint32_t kDataSize2 = 2048;
  std::ostringstream test_name_stream;
  test_name_stream << "SharedMemoryOpenExclusiveTest."
                   << Time::Now().ToDoubleT();
  std::string test_name = test_name_stream.str();

  // Open two handles to a memory segment and check that
  // open_existing_deprecated works as expected.
  SharedMemory memory1;
  bool rv = memory1.CreateNamedDeprecated(test_name, false, kDataSize);
  EXPECT_TRUE(rv);

  // Memory1 knows it's size because it created it.
  EXPECT_EQ(memory1.requested_size(), kDataSize);

  rv = memory1.Map(kDataSize);
  EXPECT_TRUE(rv);

  // The mapped memory1 must be at least the size we asked for.
  EXPECT_GE(memory1.mapped_size(), kDataSize);

  // The mapped memory1 shouldn't exceed rounding for allocation granularity.
  EXPECT_LT(memory1.mapped_size(),
            kDataSize + SysInfo::VMAllocationGranularity());

  memset(memory1.memory(), 'G', kDataSize);

  SharedMemory memory2;
  // Should not be able to create if openExisting is false.
  rv = memory2.CreateNamedDeprecated(test_name, false, kDataSize2);
  EXPECT_FALSE(rv);

  // Should be able to create with openExisting true.
  rv = memory2.CreateNamedDeprecated(test_name, true, kDataSize2);
  EXPECT_TRUE(rv);

  // Memory2 shouldn't know the size because we didn't create it.
  EXPECT_EQ(memory2.requested_size(), 0U);

  // We should be able to map the original size.
  rv = memory2.Map(kDataSize);
  EXPECT_TRUE(rv);

  // The mapped memory2 must be at least the size of the original.
  EXPECT_GE(memory2.mapped_size(), kDataSize);

  // The mapped memory2 shouldn't exceed rounding for allocation granularity.
  EXPECT_LT(memory2.mapped_size(),
            kDataSize2 + SysInfo::VMAllocationGranularity());

  // Verify that opening memory2 didn't truncate or delete memory 1.
  char* start_ptr = static_cast<char*>(memory2.memory());
  char* end_ptr = start_ptr + kDataSize;
  for (char* ptr = start_ptr; ptr < end_ptr; ptr++) {
    EXPECT_EQ(*ptr, 'G');
  }

  memory1.Close();
  memory2.Close();

  rv = memory1.Delete(test_name);
  EXPECT_TRUE(rv);
}
#endif  // !defined(OS_ANDROID) && !defined(OS_MACOSX) && !defined(OS_FUCHSIA)

// Check that memory is still mapped after its closed.
TEST_P(SharedMemoryTest, CloseNoUnmap) {
  const size_t kDataSize = 4096;

  SharedMemory memory;
  ASSERT_TRUE(memory.CreateAndMapAnonymous(kDataSize));
  char* ptr = static_cast<char*>(memory.memory());
  ASSERT_NE(ptr, static_cast<void*>(nullptr));
  memset(ptr, 'G', kDataSize);

  memory.Close();

  EXPECT_EQ(ptr, memory.memory());
  EXPECT_TRUE(!memory.handle().IsValid());

  for (size_t i = 0; i < kDataSize; i++) {
    EXPECT_EQ('G', ptr[i]);
  }

  memory.Unmap();
  EXPECT_EQ(nullptr, memory.memory());
}

#if !defined(OS_MACOSX) && !defined(OS_FUCHSIA)
// Create a set of N threads to each open a shared memory segment and write to
// it. Verify that they are always reading/writing consistent data.
TEST_P(SharedMemoryTest, MultipleThreads) {
  const int kNumThreads = 5;

  MultipleThreadMain::CleanUp();
  // On POSIX we have a problem when 2 threads try to create the shmem
  // (a file) at exactly the same time, since create both creates the
  // file and zerofills it.  We solve the problem for this unit test
  // (make it not flaky) by starting with 1 thread, then
  // intentionally don't clean up its shmem before running with
  // kNumThreads.

  int threadcounts[] = { 1, kNumThreads };
  for (size_t i = 0; i < arraysize(threadcounts); i++) {
    int numthreads = threadcounts[i];
    std::unique_ptr<PlatformThreadHandle[]> thread_handles;
    std::unique_ptr<MultipleThreadMain* []> thread_delegates;

    thread_handles.reset(new PlatformThreadHandle[numthreads]);
    thread_delegates.reset(new MultipleThreadMain*[numthreads]);

    // Spawn the threads.
    for (int16_t index = 0; index < numthreads; index++) {
      PlatformThreadHandle pth;
      thread_delegates[index] = new MultipleThreadMain(index);
      EXPECT_TRUE(PlatformThread::Create(0, thread_delegates[index], &pth));
      thread_handles[index] = pth;
    }

    // Wait for the threads to finish.
    for (int index = 0; index < numthreads; index++) {
      PlatformThread::Join(thread_handles[index]);
      delete thread_delegates[index];
    }
  }
  MultipleThreadMain::CleanUp();
}
#endif

// Allocate private (unique) shared memory with an empty string for a
// name.  Make sure several of them don't point to the same thing as
// we might expect if the names are equal.
TEST_P(SharedMemoryTest, AnonymousPrivate) {
  int i, j;
  int count = 4;
  bool rv;
  const uint32_t kDataSize = 8192;

  std::unique_ptr<SharedMemory[]> memories(new SharedMemory[count]);
  std::unique_ptr<int* []> pointers(new int*[count]);
  ASSERT_TRUE(memories.get());
  ASSERT_TRUE(pointers.get());

  for (i = 0; i < count; i++) {
    rv = memories[i].CreateAndMapAnonymous(kDataSize);
    EXPECT_TRUE(rv);
    int* ptr = static_cast<int*>(memories[i].memory());
    EXPECT_TRUE(ptr);
    pointers[i] = ptr;
  }

  for (i = 0; i < count; i++) {
    // zero out the first int in each except for i; for that one, make it 100.
    for (j = 0; j < count; j++) {
      if (i == j)
        pointers[j][0] = 100;
      else
        pointers[j][0] = 0;
    }
    // make sure there is no bleeding of the 100 into the other pointers
    for (j = 0; j < count; j++) {
      if (i == j)
        EXPECT_EQ(100, pointers[j][0]);
      else
        EXPECT_EQ(0, pointers[j][0]);
    }
  }

  for (int i = 0; i < count; i++) {
    memories[i].Close();
  }
}

TEST_P(SharedMemoryTest, GetReadOnlyHandle) {
  StringPiece contents = "Hello World";

  SharedMemory writable_shmem;
  SharedMemoryCreateOptions options;
  options.size = contents.size();
  options.share_read_only = true;
#if defined(OS_MACOSX) && !defined(OS_IOS)
  // The Mach functionality is tested in shared_memory_mac_unittest.cc.
  options.type = SharedMemoryHandle::POSIX;
#endif
  ASSERT_TRUE(writable_shmem.Create(options));
  ASSERT_TRUE(writable_shmem.Map(options.size));
  memcpy(writable_shmem.memory(), contents.data(), contents.size());
  EXPECT_TRUE(writable_shmem.Unmap());

  SharedMemoryHandle readonly_handle = writable_shmem.GetReadOnlyHandle();
  EXPECT_EQ(writable_shmem.handle().GetGUID(), readonly_handle.GetGUID());
  EXPECT_EQ(writable_shmem.handle().GetSize(), readonly_handle.GetSize());
  ASSERT_TRUE(readonly_handle.IsValid());
  SharedMemory readonly_shmem(readonly_handle, /*readonly=*/true);

  ASSERT_TRUE(readonly_shmem.Map(contents.size()));
  EXPECT_EQ(contents,
            StringPiece(static_cast<const char*>(readonly_shmem.memory()),
                        contents.size()));
  EXPECT_TRUE(readonly_shmem.Unmap());

#if defined(OS_ANDROID)
  // On Android, mapping a region through a read-only descriptor makes the
  // region read-only. Any writable mapping attempt should fail.
  ASSERT_FALSE(writable_shmem.Map(contents.size()));
#else
  // Make sure the writable instance is still writable.
  ASSERT_TRUE(writable_shmem.Map(contents.size()));
  StringPiece new_contents = "Goodbye";
  memcpy(writable_shmem.memory(), new_contents.data(),
               new_contents.size());
  EXPECT_EQ(new_contents,
            StringPiece(static_cast<const char*>(writable_shmem.memory()),
                        new_contents.size()));
#endif

  // We'd like to check that if we send the read-only segment to another
  // process, then that other process can't reopen it read/write.  (Since that
  // would be a security hole.)  Setting up multiple processes is hard in a
  // unittest, so this test checks that the *current* process can't reopen the
  // segment read/write.  I think the test here is stronger than we actually
  // care about, but there's a remote possibility that sending a file over a
  // pipe would transform it into read/write.
  SharedMemoryHandle handle = readonly_shmem.handle();

#if defined(OS_ANDROID)
  // The "read-only" handle is still writable on Android:
  // http://crbug.com/320865
  (void)handle;
#elif defined(OS_FUCHSIA)
  uintptr_t addr;
  EXPECT_NE(ZX_OK, zx::vmar::root_self()->map(
                       0, *zx::unowned_vmo(handle.GetHandle()), 0,
                       contents.size(), ZX_VM_FLAG_PERM_WRITE, &addr))
      << "Shouldn't be able to map as writable.";

  zx::vmo duped_handle;
  EXPECT_NE(ZX_OK, zx::unowned_vmo(handle.GetHandle())
                       ->duplicate(ZX_RIGHT_WRITE, &duped_handle))
      << "Shouldn't be able to duplicate the handle into a writable one.";

  EXPECT_EQ(ZX_OK, zx::unowned_vmo(handle.GetHandle())
                       ->duplicate(ZX_RIGHT_READ, &duped_handle))
      << "Should be able to duplicate the handle into a readable one.";
#elif defined(OS_POSIX)
  int handle_fd = SharedMemory::GetFdFromSharedMemoryHandle(handle);
  EXPECT_EQ(O_RDONLY, fcntl(handle_fd, F_GETFL) & O_ACCMODE)
      << "The descriptor itself should be read-only.";

  errno = 0;
  void* writable = mmap(nullptr, contents.size(), PROT_READ | PROT_WRITE,
                        MAP_SHARED, handle_fd, 0);
  int mmap_errno = errno;
  EXPECT_EQ(MAP_FAILED, writable)
      << "It shouldn't be possible to re-mmap the descriptor writable.";
  EXPECT_EQ(EACCES, mmap_errno) << strerror(mmap_errno);
  if (writable != MAP_FAILED)
    EXPECT_EQ(0, munmap(writable, readonly_shmem.mapped_size()));

#elif defined(OS_WIN)
  EXPECT_EQ(NULL, MapViewOfFile(handle.GetHandle(), FILE_MAP_WRITE, 0, 0, 0))
      << "Shouldn't be able to map memory writable.";

  HANDLE temp_handle;
  BOOL rv = ::DuplicateHandle(GetCurrentProcess(), handle.GetHandle(),
                              GetCurrentProcess(), &temp_handle,
                              FILE_MAP_ALL_ACCESS, false, 0);
  EXPECT_EQ(FALSE, rv)
      << "Shouldn't be able to duplicate the handle into a writable one.";
  if (rv)
    win::ScopedHandle writable_handle(temp_handle);
  rv = ::DuplicateHandle(GetCurrentProcess(), handle.GetHandle(),
                         GetCurrentProcess(), &temp_handle, FILE_MAP_READ,
                         false, 0);
  EXPECT_EQ(TRUE, rv)
      << "Should be able to duplicate the handle into a readable one.";
  if (rv)
    win::ScopedHandle writable_handle(temp_handle);
#else
#error Unexpected platform; write a test that tries to make 'handle' writable.
#endif  // defined(OS_POSIX) || defined(OS_WIN)
}

TEST_P(SharedMemoryTest, ShareToSelf) {
  StringPiece contents = "Hello World";

  SharedMemory shmem;
  ASSERT_TRUE(shmem.CreateAndMapAnonymous(contents.size()));
  memcpy(shmem.memory(), contents.data(), contents.size());
  EXPECT_TRUE(shmem.Unmap());

  SharedMemoryHandle shared_handle = shmem.handle().Duplicate();
  ASSERT_TRUE(shared_handle.IsValid());
  EXPECT_TRUE(shared_handle.OwnershipPassesToIPC());
  EXPECT_EQ(shared_handle.GetGUID(), shmem.handle().GetGUID());
  EXPECT_EQ(shared_handle.GetSize(), shmem.handle().GetSize());
  SharedMemory shared(shared_handle, /*readonly=*/false);

  ASSERT_TRUE(shared.Map(contents.size()));
  EXPECT_EQ(
      contents,
      StringPiece(static_cast<const char*>(shared.memory()), contents.size()));

  shared_handle = shmem.handle().Duplicate();
  ASSERT_TRUE(shared_handle.IsValid());
  ASSERT_TRUE(shared_handle.OwnershipPassesToIPC());
  SharedMemory readonly(shared_handle, /*readonly=*/true);

  ASSERT_TRUE(readonly.Map(contents.size()));
  EXPECT_EQ(contents,
            StringPiece(static_cast<const char*>(readonly.memory()),
                        contents.size()));
}

TEST_P(SharedMemoryTest, ShareWithMultipleInstances) {
  static const StringPiece kContents = "Hello World";

  SharedMemory shmem;
  ASSERT_TRUE(shmem.CreateAndMapAnonymous(kContents.size()));
  // We do not need to unmap |shmem| to let |shared| map.
  const StringPiece shmem_contents(static_cast<const char*>(shmem.memory()),
                                   shmem.requested_size());

  SharedMemoryHandle shared_handle = shmem.handle().Duplicate();
  ASSERT_TRUE(shared_handle.IsValid());
  SharedMemory shared(shared_handle, /*readonly=*/false);
  ASSERT_TRUE(shared.Map(kContents.size()));
  // The underlying shared memory is created by |shmem|, so both
  // |shared|.requested_size() and |readonly|.requested_size() are zero.
  ASSERT_EQ(0U, shared.requested_size());
  const StringPiece shared_contents(static_cast<const char*>(shared.memory()),
                                    shmem.requested_size());

  shared_handle = shmem.handle().Duplicate();
  ASSERT_TRUE(shared_handle.IsValid());
  ASSERT_TRUE(shared_handle.OwnershipPassesToIPC());
  SharedMemory readonly(shared_handle, /*readonly=*/true);
  ASSERT_TRUE(readonly.Map(kContents.size()));
  ASSERT_EQ(0U, readonly.requested_size());
  const StringPiece readonly_contents(
      static_cast<const char*>(readonly.memory()),
      shmem.requested_size());

  // |shmem| should be able to update the content.
  memcpy(shmem.memory(), kContents.data(), kContents.size());

  ASSERT_EQ(kContents, shmem_contents);
  ASSERT_EQ(kContents, shared_contents);
  ASSERT_EQ(kContents, readonly_contents);

  // |shared| should also be able to update the content.
  memcpy(shared.memory(), ToLowerASCII(kContents).c_str(),
               kContents.size());

  ASSERT_EQ(StringPiece(ToLowerASCII(kContents)), shmem_contents);
  ASSERT_EQ(StringPiece(ToLowerASCII(kContents)), shared_contents);
  ASSERT_EQ(StringPiece(ToLowerASCII(kContents)), readonly_contents);
}

TEST_P(SharedMemoryTest, MapAt) {
  ASSERT_TRUE(SysInfo::VMAllocationGranularity() >= sizeof(uint32_t));
  const size_t kCount = SysInfo::VMAllocationGranularity();
  const size_t kDataSize = kCount * sizeof(uint32_t);

  SharedMemory memory;
  ASSERT_TRUE(memory.CreateAndMapAnonymous(kDataSize));
  uint32_t* ptr = static_cast<uint32_t*>(memory.memory());
  ASSERT_NE(ptr, static_cast<void*>(nullptr));

  for (size_t i = 0; i < kCount; ++i) {
    ptr[i] = i;
  }

  memory.Unmap();

  off_t offset = SysInfo::VMAllocationGranularity();
  ASSERT_TRUE(memory.MapAt(offset, kDataSize - offset));
  offset /= sizeof(uint32_t);
  ptr = static_cast<uint32_t*>(memory.memory());
  ASSERT_NE(ptr, static_cast<void*>(nullptr));
  for (size_t i = offset; i < kCount; ++i) {
    EXPECT_EQ(ptr[i - offset], i);
  }
}

TEST_P(SharedMemoryTest, MapTwice) {
  const uint32_t kDataSize = 1024;
  SharedMemory memory;
  bool rv = memory.CreateAndMapAnonymous(kDataSize);
  EXPECT_TRUE(rv);

  void* old_address = memory.memory();

  rv = memory.Map(kDataSize);
  EXPECT_FALSE(rv);
  EXPECT_EQ(old_address, memory.memory());
}

#if defined(OS_POSIX)
// This test is not applicable for iOS (crbug.com/399384).
#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;
  SharedMemoryCreateOptions options;
  options.size = kTestSize;
  options.executable = true;
#if defined(OS_MACOSX) && !defined(OS_IOS)
  // The Mach functionality is tested in shared_memory_mac_unittest.cc.
  options.type = SharedMemoryHandle::POSIX;
#endif

  EXPECT_TRUE(shared_memory.Create(options));
  EXPECT_TRUE(shared_memory.Map(shared_memory.requested_size()));

  EXPECT_EQ(0, mprotect(shared_memory.memory(), shared_memory.requested_size(),
                        PROT_READ | PROT_EXEC));
}
#endif  // !defined(OS_IOS)

#if defined(OS_ANDROID)
// This test is restricted to Android since there is no way on other platforms
// to guarantee that a region can never be mapped with PROT_EXEC. E.g. on
// Linux, anonymous shared regions come from /dev/shm which can be mounted
// without 'noexec'. In this case, anything can perform an mprotect() to
// change the protection mask of a given page.
TEST(SharedMemoryTest, AnonymousIsNotExecutableByDefault) {
  const uint32_t kTestSize = 1 << 16;

  SharedMemory shared_memory;
  SharedMemoryCreateOptions options;
  options.size = kTestSize;

  EXPECT_TRUE(shared_memory.Create(options));
  EXPECT_TRUE(shared_memory.Map(shared_memory.requested_size()));

  errno = 0;
  EXPECT_EQ(-1, mprotect(shared_memory.memory(), shared_memory.requested_size(),
                         PROT_READ | PROT_EXEC));
  EXPECT_EQ(EACCES, errno);
}
#endif  // OS_ANDROID

// Android supports a different permission model than POSIX for its "ashmem"
// shared memory implementation. So the tests about file permissions are not
// included on Android. Fuchsia does not use a file-backed shared memory
// implementation.

#if !defined(OS_ANDROID) && !defined(OS_FUCHSIA)

// Set a umask and restore the old mask on destruction.
class ScopedUmaskSetter {
 public:
  explicit ScopedUmaskSetter(mode_t target_mask) {
    old_umask_ = umask(target_mask);
  }
  ~ScopedUmaskSetter() { umask(old_umask_); }
 private:
  mode_t old_umask_;
  DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedUmaskSetter);
};

// Create a shared memory object, check its permissions.
TEST_P(SharedMemoryTest, FilePermissionsAnonymous) {
  const uint32_t kTestSize = 1 << 8;

  SharedMemory shared_memory;
  SharedMemoryCreateOptions options;
  options.size = kTestSize;
#if defined(OS_MACOSX) && !defined(OS_IOS)
  // The Mach functionality is tested in shared_memory_mac_unittest.cc.
  options.type = SharedMemoryHandle::POSIX;
#endif
  // Set a file mode creation mask that gives all permissions.
  ScopedUmaskSetter permissive_mask(S_IWGRP | S_IWOTH);

  EXPECT_TRUE(shared_memory.Create(options));

  int shm_fd =
      SharedMemory::GetFdFromSharedMemoryHandle(shared_memory.handle());
  struct stat shm_stat;
  EXPECT_EQ(0, fstat(shm_fd, &shm_stat));
  // Neither the group, nor others should be able to read the shared memory
  // file.
  EXPECT_FALSE(shm_stat.st_mode & S_IRWXO);
  EXPECT_FALSE(shm_stat.st_mode & S_IRWXG);
}

// Create a shared memory object, check its permissions.
TEST_P(SharedMemoryTest, FilePermissionsNamed) {
  const uint32_t kTestSize = 1 << 8;

  SharedMemory shared_memory;
  SharedMemoryCreateOptions options;
  options.size = kTestSize;
#if defined(OS_MACOSX) && !defined(OS_IOS)
  // The Mach functionality is tested in shared_memory_mac_unittest.cc.
  options.type = SharedMemoryHandle::POSIX;
#endif

  // Set a file mode creation mask that gives all permissions.
  ScopedUmaskSetter permissive_mask(S_IWGRP | S_IWOTH);

  EXPECT_TRUE(shared_memory.Create(options));

  int fd = SharedMemory::GetFdFromSharedMemoryHandle(shared_memory.handle());
  struct stat shm_stat;
  EXPECT_EQ(0, fstat(fd, &shm_stat));
  // Neither the group, nor others should have been able to open the shared
  // memory file while its name existed.
  EXPECT_FALSE(shm_stat.st_mode & S_IRWXO);
  EXPECT_FALSE(shm_stat.st_mode & S_IRWXG);
}
#endif  // !defined(OS_ANDROID) && !defined(OS_FUCHSIA)

#endif  // defined(OS_POSIX)

// Map() will return addresses which are aligned to the platform page size, this
// varies from platform to platform though.  Since we'd like to advertise a
// minimum alignment that callers can count on, test for it here.
TEST_P(SharedMemoryTest, MapMinimumAlignment) {
  static const int kDataSize = 8192;

  SharedMemory shared_memory;
  ASSERT_TRUE(shared_memory.CreateAndMapAnonymous(kDataSize));
  EXPECT_EQ(0U, reinterpret_cast<uintptr_t>(
      shared_memory.memory()) & (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1));
  shared_memory.Close();
}

#if defined(OS_WIN)
TEST_P(SharedMemoryTest, UnsafeImageSection) {
  const char kTestSectionName[] = "UnsafeImageSection";
  wchar_t path[MAX_PATH];
  EXPECT_GT(::GetModuleFileName(nullptr, path, arraysize(path)), 0U);

  // Map the current executable image to save us creating a new PE file on disk.
  base::win::ScopedHandle file_handle(::CreateFile(
      path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr));
  EXPECT_TRUE(file_handle.IsValid());
  base::win::ScopedHandle section_handle(
      ::CreateFileMappingA(file_handle.Get(), nullptr,
                           PAGE_READONLY | SEC_IMAGE, 0, 0, kTestSectionName));
  EXPECT_TRUE(section_handle.IsValid());

  // Check direct opening by name, from handle and duplicated from handle.
  SharedMemory shared_memory_open;
  EXPECT_TRUE(shared_memory_open.Open(kTestSectionName, true));
  EXPECT_FALSE(shared_memory_open.Map(1));
  EXPECT_EQ(nullptr, shared_memory_open.memory());

  SharedMemory shared_memory_handle_local(
      SharedMemoryHandle(section_handle.Take(), 1, UnguessableToken::Create()),
      true);
  EXPECT_FALSE(shared_memory_handle_local.Map(1));
  EXPECT_EQ(nullptr, shared_memory_handle_local.memory());

  // Check that a handle without SECTION_QUERY also can't be mapped as it can't
  // be checked.
  SharedMemory shared_memory_handle_dummy;
  SharedMemoryCreateOptions options;
  options.size = 0x1000;
  EXPECT_TRUE(shared_memory_handle_dummy.Create(options));
  HANDLE handle_no_query;
  EXPECT_TRUE(::DuplicateHandle(
      ::GetCurrentProcess(), shared_memory_handle_dummy.handle().GetHandle(),
      ::GetCurrentProcess(), &handle_no_query, FILE_MAP_READ, FALSE, 0));
  SharedMemory shared_memory_handle_no_query(
      SharedMemoryHandle(handle_no_query, options.size,
                         UnguessableToken::Create()),
      true);
  EXPECT_FALSE(shared_memory_handle_no_query.Map(1));
  EXPECT_EQ(nullptr, shared_memory_handle_no_query.memory());
}
#endif  // defined(OS_WIN)

// iOS does not allow multiple processes.
// Android ashmem does not support named shared memory.
// Fuchsia SharedMemory does not support named shared memory.
// Mac SharedMemory does not support named shared memory. crbug.com/345734
#if !defined(OS_IOS) && !defined(OS_ANDROID) && !defined(OS_MACOSX) && \
    !defined(OS_FUCHSIA)
// On POSIX it is especially important we test shmem across processes,
// not just across threads.  But the test is enabled on all platforms.
class SharedMemoryProcessTest : public MultiProcessTest {
 public:
  static void CleanUp() {
    SharedMemory memory;
    memory.Delete(s_test_name_);
  }

  static int TaskTestMain() {
    int errors = 0;
    SharedMemory memory;
    bool rv = memory.CreateNamedDeprecated(s_test_name_, true, s_data_size_);
    EXPECT_TRUE(rv);
    if (rv != true)
      errors++;
    rv = memory.Map(s_data_size_);
    EXPECT_TRUE(rv);
    if (rv != true)
      errors++;
    int* ptr = static_cast<int*>(memory.memory());

    // This runs concurrently in multiple processes. Writes need to be atomic.
    subtle::Barrier_AtomicIncrement(ptr, 1);
    memory.Close();
    return errors;
  }

  static const char s_test_name_[];
  static const uint32_t s_data_size_;
};

const char SharedMemoryProcessTest::s_test_name_[] = "MPMem";
const uint32_t SharedMemoryProcessTest::s_data_size_ = 1024;

TEST_F(SharedMemoryProcessTest, SharedMemoryAcrossProcesses) {
  const int kNumTasks = 5;

  SharedMemoryProcessTest::CleanUp();

  // Create a shared memory region. Set the first word to 0.
  SharedMemory memory;
  bool rv = memory.CreateNamedDeprecated(s_test_name_, true, s_data_size_);
  ASSERT_TRUE(rv);
  rv = memory.Map(s_data_size_);
  ASSERT_TRUE(rv);
  int* ptr = static_cast<int*>(memory.memory());
  *ptr = 0;

  // Start |kNumTasks| processes, each of which atomically increments the first
  // word by 1.
  Process processes[kNumTasks];
  for (int index = 0; index < kNumTasks; ++index) {
    processes[index] = SpawnChild("SharedMemoryTestMain");
    ASSERT_TRUE(processes[index].IsValid());
  }

  // Check that each process exited correctly.
  int exit_code = 0;
  for (int index = 0; index < kNumTasks; ++index) {
    EXPECT_TRUE(processes[index].WaitForExit(&exit_code));
    EXPECT_EQ(0, exit_code);
  }

  // Check that the shared memory region reflects |kNumTasks| increments.
  ASSERT_EQ(kNumTasks, *ptr);

  memory.Close();
  SharedMemoryProcessTest::CleanUp();
}

MULTIPROCESS_TEST_MAIN(SharedMemoryTestMain) {
  return SharedMemoryProcessTest::TaskTestMain();
}
#endif  // !defined(OS_IOS) && !defined(OS_ANDROID) && !defined(OS_MACOSX) &&
        // !defined(OS_FUCHSIA)

TEST_P(SharedMemoryTest, MappedId) {
  const uint32_t kDataSize = 1024;
  SharedMemory memory;
  SharedMemoryCreateOptions options;
  options.size = kDataSize;
#if defined(OS_MACOSX) && !defined(OS_IOS)
  // The Mach functionality is tested in shared_memory_mac_unittest.cc.
  options.type = SharedMemoryHandle::POSIX;
#endif

  EXPECT_TRUE(memory.Create(options));
  base::UnguessableToken id = memory.handle().GetGUID();
  EXPECT_FALSE(id.is_empty());
  EXPECT_TRUE(memory.mapped_id().is_empty());

  EXPECT_TRUE(memory.Map(kDataSize));
  EXPECT_EQ(id, memory.mapped_id());

  memory.Close();
  EXPECT_EQ(id, memory.mapped_id());

  memory.Unmap();
  EXPECT_TRUE(memory.mapped_id().is_empty());
}

INSTANTIATE_TEST_CASE_P(Default,
                        SharedMemoryTest,
                        ::testing::Values(Mode::Default));
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
INSTANTIATE_TEST_CASE_P(SkipDevShm,
                        SharedMemoryTest,
                        ::testing::Values(Mode::DisableDevShm));
#endif  // defined(OS_LINUX) && !defined(OS_CHROMEOS)

#if defined(OS_ANDROID)
TEST(SharedMemoryTest, ReadOnlyRegions) {
  const uint32_t kDataSize = 1024;
  SharedMemory memory;
  SharedMemoryCreateOptions options;
  options.size = kDataSize;
  EXPECT_TRUE(memory.Create(options));

  EXPECT_FALSE(memory.handle().IsRegionReadOnly());

  // Check that it is possible to map the region directly from the fd.
  int region_fd = memory.handle().GetHandle();
  EXPECT_GE(region_fd, 0);
  void* address = mmap(nullptr, kDataSize, PROT_READ | PROT_WRITE, MAP_SHARED,
                       region_fd, 0);
  bool success = address && address != MAP_FAILED;
  ASSERT_TRUE(address);
  ASSERT_NE(address, MAP_FAILED);
  if (success) {
    EXPECT_EQ(0, munmap(address, kDataSize));
  }

  ASSERT_TRUE(memory.handle().SetRegionReadOnly());
  EXPECT_TRUE(memory.handle().IsRegionReadOnly());

  // Check that it is no longer possible to map the region read/write.
  errno = 0;
  address = mmap(nullptr, kDataSize, PROT_READ | PROT_WRITE, MAP_SHARED,
                 region_fd, 0);
  success = address && address != MAP_FAILED;
  ASSERT_FALSE(success);
  ASSERT_EQ(EPERM, errno);
  if (success) {
    EXPECT_EQ(0, munmap(address, kDataSize));
  }
}

TEST(SharedMemoryTest, ReadOnlyDescriptors) {
  const uint32_t kDataSize = 1024;
  SharedMemory memory;
  SharedMemoryCreateOptions options;
  options.size = kDataSize;
  EXPECT_TRUE(memory.Create(options));

  EXPECT_FALSE(memory.handle().IsRegionReadOnly());

  // Getting a read-only descriptor should not make the region read-only itself.
  SharedMemoryHandle ro_handle = memory.GetReadOnlyHandle();
  EXPECT_FALSE(memory.handle().IsRegionReadOnly());

  // Mapping a writable region from a read-only descriptor should not
  // be possible, it will DCHECK() in debug builds (see test below),
  // while returning false on release ones.
  {
    bool dcheck_fired = false;
    logging::ScopedLogAssertHandler log_assert(
        base::BindRepeating([](bool* flag, const char*, int, base::StringPiece,
                               base::StringPiece) { *flag = true; },
                            base::Unretained(&dcheck_fired)));

    SharedMemory rw_region(ro_handle.Duplicate(), /* read_only */ false);
    EXPECT_FALSE(rw_region.Map(kDataSize));
    EXPECT_EQ(DCHECK_IS_ON() ? true : false, dcheck_fired);
  }

  // Nor shall it turn the region read-only itself.
  EXPECT_FALSE(ro_handle.IsRegionReadOnly());

  // Mapping a read-only region from a read-only descriptor should work.
  SharedMemory ro_region(ro_handle.Duplicate(), /* read_only */ true);
  EXPECT_TRUE(ro_region.Map(kDataSize));

  // And it should turn the region read-only too.
  EXPECT_TRUE(ro_handle.IsRegionReadOnly());
  EXPECT_TRUE(memory.handle().IsRegionReadOnly());
  EXPECT_FALSE(memory.Map(kDataSize));

  ro_handle.Close();
}

#endif  // OS_ANDROID

}  // namespace base
