Home | History | Annotate | Download | only in memory
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/memory/shared_memory.h"
      6 
      7 #include <stddef.h>
      8 #include <stdint.h>
      9 
     10 #include <memory>
     11 
     12 #include "base/atomicops.h"
     13 #include "base/macros.h"
     14 #include "base/memory/shared_memory_handle.h"
     15 #include "base/process/kill.h"
     16 #include "base/rand_util.h"
     17 #include "base/strings/string_number_conversions.h"
     18 #include "base/sys_info.h"
     19 #include "base/test/multiprocess_test.h"
     20 #include "base/threading/platform_thread.h"
     21 #include "base/time/time.h"
     22 #include "build/build_config.h"
     23 #include "testing/gtest/include/gtest/gtest.h"
     24 #include "testing/multiprocess_func_list.h"
     25 
     26 #if defined(OS_POSIX)
     27 #include <errno.h>
     28 #include <fcntl.h>
     29 #include <sys/mman.h>
     30 #include <sys/stat.h>
     31 #include <sys/types.h>
     32 #include <unistd.h>
     33 #endif
     34 
     35 #if defined(OS_WIN)
     36 #include "base/win/scoped_handle.h"
     37 #endif
     38 
     39 namespace base {
     40 
     41 namespace {
     42 
     43 #if !defined(OS_MACOSX)
     44 // Each thread will open the shared memory.  Each thread will take a different 4
     45 // byte int pointer, and keep changing it, with some small pauses in between.
     46 // Verify that each thread's value in the shared memory is always correct.
     47 class MultipleThreadMain : public PlatformThread::Delegate {
     48  public:
     49   explicit MultipleThreadMain(int16_t id) : id_(id) {}
     50   ~MultipleThreadMain() override {}
     51 
     52   static void CleanUp() {
     53     SharedMemory memory;
     54     memory.Delete(s_test_name_);
     55   }
     56 
     57   // PlatformThread::Delegate interface.
     58   void ThreadMain() override {
     59     const uint32_t kDataSize = 1024;
     60     SharedMemory memory;
     61     bool rv = memory.CreateNamedDeprecated(s_test_name_, true, kDataSize);
     62     EXPECT_TRUE(rv);
     63     rv = memory.Map(kDataSize);
     64     EXPECT_TRUE(rv);
     65     int* ptr = static_cast<int*>(memory.memory()) + id_;
     66     EXPECT_EQ(0, *ptr);
     67 
     68     for (int idx = 0; idx < 100; idx++) {
     69       *ptr = idx;
     70       PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));
     71       EXPECT_EQ(*ptr, idx);
     72     }
     73     // Reset back to 0 for the next test that uses the same name.
     74     *ptr = 0;
     75 
     76     memory.Close();
     77   }
     78 
     79  private:
     80   int16_t id_;
     81 
     82   static const char s_test_name_[];
     83 
     84   DISALLOW_COPY_AND_ASSIGN(MultipleThreadMain);
     85 };
     86 
     87 const char MultipleThreadMain::s_test_name_[] =
     88     "SharedMemoryOpenThreadTest";
     89 #endif  // !defined(OS_MACOSX)
     90 
     91 }  // namespace
     92 
     93 // Android/Mac doesn't support SharedMemory::Open/Delete/
     94 // CreateNamedDeprecated(openExisting=true)
     95 #if !defined(OS_ANDROID) && !defined(OS_MACOSX)
     96 TEST(SharedMemoryTest, OpenClose) {
     97   const uint32_t kDataSize = 1024;
     98   std::string test_name = "SharedMemoryOpenCloseTest";
     99 
    100   // Open two handles to a memory segment, confirm that they are mapped
    101   // separately yet point to the same space.
    102   SharedMemory memory1;
    103   bool rv = memory1.Delete(test_name);
    104   EXPECT_TRUE(rv);
    105   rv = memory1.Delete(test_name);
    106   EXPECT_TRUE(rv);
    107   rv = memory1.Open(test_name, false);
    108   EXPECT_FALSE(rv);
    109   rv = memory1.CreateNamedDeprecated(test_name, false, kDataSize);
    110   EXPECT_TRUE(rv);
    111   rv = memory1.Map(kDataSize);
    112   EXPECT_TRUE(rv);
    113   SharedMemory memory2;
    114   rv = memory2.Open(test_name, false);
    115   EXPECT_TRUE(rv);
    116   rv = memory2.Map(kDataSize);
    117   EXPECT_TRUE(rv);
    118   EXPECT_NE(memory1.memory(), memory2.memory());  // Compare the pointers.
    119 
    120   // Make sure we don't segfault. (it actually happened!)
    121   ASSERT_NE(memory1.memory(), static_cast<void*>(NULL));
    122   ASSERT_NE(memory2.memory(), static_cast<void*>(NULL));
    123 
    124   // Write data to the first memory segment, verify contents of second.
    125   memset(memory1.memory(), '1', kDataSize);
    126   EXPECT_EQ(memcmp(memory1.memory(), memory2.memory(), kDataSize), 0);
    127 
    128   // Close the first memory segment, and verify the second has the right data.
    129   memory1.Close();
    130   char* start_ptr = static_cast<char*>(memory2.memory());
    131   char* end_ptr = start_ptr + kDataSize;
    132   for (char* ptr = start_ptr; ptr < end_ptr; ptr++)
    133     EXPECT_EQ(*ptr, '1');
    134 
    135   // Close the second memory segment.
    136   memory2.Close();
    137 
    138   rv = memory1.Delete(test_name);
    139   EXPECT_TRUE(rv);
    140   rv = memory2.Delete(test_name);
    141   EXPECT_TRUE(rv);
    142 }
    143 
    144 TEST(SharedMemoryTest, OpenExclusive) {
    145   const uint32_t kDataSize = 1024;
    146   const uint32_t kDataSize2 = 2048;
    147   std::ostringstream test_name_stream;
    148   test_name_stream << "SharedMemoryOpenExclusiveTest."
    149                    << Time::Now().ToDoubleT();
    150   std::string test_name = test_name_stream.str();
    151 
    152   // Open two handles to a memory segment and check that
    153   // open_existing_deprecated works as expected.
    154   SharedMemory memory1;
    155   bool rv = memory1.CreateNamedDeprecated(test_name, false, kDataSize);
    156   EXPECT_TRUE(rv);
    157 
    158   // Memory1 knows it's size because it created it.
    159   EXPECT_EQ(memory1.requested_size(), kDataSize);
    160 
    161   rv = memory1.Map(kDataSize);
    162   EXPECT_TRUE(rv);
    163 
    164   // The mapped memory1 must be at least the size we asked for.
    165   EXPECT_GE(memory1.mapped_size(), kDataSize);
    166 
    167   // The mapped memory1 shouldn't exceed rounding for allocation granularity.
    168   EXPECT_LT(memory1.mapped_size(),
    169             kDataSize + SysInfo::VMAllocationGranularity());
    170 
    171   memset(memory1.memory(), 'G', kDataSize);
    172 
    173   SharedMemory memory2;
    174   // Should not be able to create if openExisting is false.
    175   rv = memory2.CreateNamedDeprecated(test_name, false, kDataSize2);
    176   EXPECT_FALSE(rv);
    177 
    178   // Should be able to create with openExisting true.
    179   rv = memory2.CreateNamedDeprecated(test_name, true, kDataSize2);
    180   EXPECT_TRUE(rv);
    181 
    182   // Memory2 shouldn't know the size because we didn't create it.
    183   EXPECT_EQ(memory2.requested_size(), 0U);
    184 
    185   // We should be able to map the original size.
    186   rv = memory2.Map(kDataSize);
    187   EXPECT_TRUE(rv);
    188 
    189   // The mapped memory2 must be at least the size of the original.
    190   EXPECT_GE(memory2.mapped_size(), kDataSize);
    191 
    192   // The mapped memory2 shouldn't exceed rounding for allocation granularity.
    193   EXPECT_LT(memory2.mapped_size(),
    194             kDataSize2 + SysInfo::VMAllocationGranularity());
    195 
    196   // Verify that opening memory2 didn't truncate or delete memory 1.
    197   char* start_ptr = static_cast<char*>(memory2.memory());
    198   char* end_ptr = start_ptr + kDataSize;
    199   for (char* ptr = start_ptr; ptr < end_ptr; ptr++) {
    200     EXPECT_EQ(*ptr, 'G');
    201   }
    202 
    203   memory1.Close();
    204   memory2.Close();
    205 
    206   rv = memory1.Delete(test_name);
    207   EXPECT_TRUE(rv);
    208 }
    209 #endif  // !defined(OS_ANDROID) && !defined(OS_MACOSX)
    210 
    211 // Check that memory is still mapped after its closed.
    212 TEST(SharedMemoryTest, CloseNoUnmap) {
    213   const size_t kDataSize = 4096;
    214 
    215   SharedMemory memory;
    216   ASSERT_TRUE(memory.CreateAndMapAnonymous(kDataSize));
    217   char* ptr = static_cast<char*>(memory.memory());
    218   ASSERT_NE(ptr, static_cast<void*>(NULL));
    219   memset(ptr, 'G', kDataSize);
    220 
    221   memory.Close();
    222 
    223   EXPECT_EQ(ptr, memory.memory());
    224   EXPECT_EQ(SharedMemory::NULLHandle(), memory.handle());
    225 
    226   for (size_t i = 0; i < kDataSize; i++) {
    227     EXPECT_EQ('G', ptr[i]);
    228   }
    229 
    230   memory.Unmap();
    231   EXPECT_EQ(nullptr, memory.memory());
    232 }
    233 
    234 #if !defined(OS_MACOSX)
    235 // Create a set of N threads to each open a shared memory segment and write to
    236 // it. Verify that they are always reading/writing consistent data.
    237 TEST(SharedMemoryTest, MultipleThreads) {
    238   const int kNumThreads = 5;
    239 
    240   MultipleThreadMain::CleanUp();
    241   // On POSIX we have a problem when 2 threads try to create the shmem
    242   // (a file) at exactly the same time, since create both creates the
    243   // file and zerofills it.  We solve the problem for this unit test
    244   // (make it not flaky) by starting with 1 thread, then
    245   // intentionally don't clean up its shmem before running with
    246   // kNumThreads.
    247 
    248   int threadcounts[] = { 1, kNumThreads };
    249   for (size_t i = 0; i < arraysize(threadcounts); i++) {
    250     int numthreads = threadcounts[i];
    251     std::unique_ptr<PlatformThreadHandle[]> thread_handles;
    252     std::unique_ptr<MultipleThreadMain* []> thread_delegates;
    253 
    254     thread_handles.reset(new PlatformThreadHandle[numthreads]);
    255     thread_delegates.reset(new MultipleThreadMain*[numthreads]);
    256 
    257     // Spawn the threads.
    258     for (int16_t index = 0; index < numthreads; index++) {
    259       PlatformThreadHandle pth;
    260       thread_delegates[index] = new MultipleThreadMain(index);
    261       EXPECT_TRUE(PlatformThread::Create(0, thread_delegates[index], &pth));
    262       thread_handles[index] = pth;
    263     }
    264 
    265     // Wait for the threads to finish.
    266     for (int index = 0; index < numthreads; index++) {
    267       PlatformThread::Join(thread_handles[index]);
    268       delete thread_delegates[index];
    269     }
    270   }
    271   MultipleThreadMain::CleanUp();
    272 }
    273 #endif
    274 
    275 // Allocate private (unique) shared memory with an empty string for a
    276 // name.  Make sure several of them don't point to the same thing as
    277 // we might expect if the names are equal.
    278 TEST(SharedMemoryTest, AnonymousPrivate) {
    279   int i, j;
    280   int count = 4;
    281   bool rv;
    282   const uint32_t kDataSize = 8192;
    283 
    284   std::unique_ptr<SharedMemory[]> memories(new SharedMemory[count]);
    285   std::unique_ptr<int* []> pointers(new int*[count]);
    286   ASSERT_TRUE(memories.get());
    287   ASSERT_TRUE(pointers.get());
    288 
    289   for (i = 0; i < count; i++) {
    290     rv = memories[i].CreateAndMapAnonymous(kDataSize);
    291     EXPECT_TRUE(rv);
    292     int* ptr = static_cast<int*>(memories[i].memory());
    293     EXPECT_TRUE(ptr);
    294     pointers[i] = ptr;
    295   }
    296 
    297   for (i = 0; i < count; i++) {
    298     // zero out the first int in each except for i; for that one, make it 100.
    299     for (j = 0; j < count; j++) {
    300       if (i == j)
    301         pointers[j][0] = 100;
    302       else
    303         pointers[j][0] = 0;
    304     }
    305     // make sure there is no bleeding of the 100 into the other pointers
    306     for (j = 0; j < count; j++) {
    307       if (i == j)
    308         EXPECT_EQ(100, pointers[j][0]);
    309       else
    310         EXPECT_EQ(0, pointers[j][0]);
    311     }
    312   }
    313 
    314   for (int i = 0; i < count; i++) {
    315     memories[i].Close();
    316   }
    317 }
    318 
    319 TEST(SharedMemoryTest, ShareReadOnly) {
    320   StringPiece contents = "Hello World";
    321 
    322   SharedMemory writable_shmem;
    323   SharedMemoryCreateOptions options;
    324   options.size = contents.size();
    325   options.share_read_only = true;
    326 #if defined(OS_MACOSX) && !defined(OS_IOS)
    327   // The Mach functionality is tested in shared_memory_mac_unittest.cc.
    328   options.type = SharedMemoryHandle::POSIX;
    329 #endif
    330   ASSERT_TRUE(writable_shmem.Create(options));
    331   ASSERT_TRUE(writable_shmem.Map(options.size));
    332   memcpy(writable_shmem.memory(), contents.data(), contents.size());
    333   EXPECT_TRUE(writable_shmem.Unmap());
    334 
    335   SharedMemoryHandle readonly_handle;
    336   ASSERT_TRUE(writable_shmem.ShareReadOnlyToProcess(GetCurrentProcessHandle(),
    337                                                     &readonly_handle));
    338   SharedMemory readonly_shmem(readonly_handle, /*readonly=*/true);
    339 
    340   ASSERT_TRUE(readonly_shmem.Map(contents.size()));
    341   EXPECT_EQ(contents,
    342             StringPiece(static_cast<const char*>(readonly_shmem.memory()),
    343                         contents.size()));
    344   EXPECT_TRUE(readonly_shmem.Unmap());
    345 
    346   // Make sure the writable instance is still writable.
    347   ASSERT_TRUE(writable_shmem.Map(contents.size()));
    348   StringPiece new_contents = "Goodbye";
    349   memcpy(writable_shmem.memory(), new_contents.data(), new_contents.size());
    350   EXPECT_EQ(new_contents,
    351             StringPiece(static_cast<const char*>(writable_shmem.memory()),
    352                         new_contents.size()));
    353 
    354   // We'd like to check that if we send the read-only segment to another
    355   // process, then that other process can't reopen it read/write.  (Since that
    356   // would be a security hole.)  Setting up multiple processes is hard in a
    357   // unittest, so this test checks that the *current* process can't reopen the
    358   // segment read/write.  I think the test here is stronger than we actually
    359   // care about, but there's a remote possibility that sending a file over a
    360   // pipe would transform it into read/write.
    361   SharedMemoryHandle handle = readonly_shmem.handle();
    362 
    363 #if defined(OS_ANDROID)
    364   // The "read-only" handle is still writable on Android:
    365   // http://crbug.com/320865
    366   (void)handle;
    367 #elif defined(OS_POSIX)
    368   int handle_fd = SharedMemory::GetFdFromSharedMemoryHandle(handle);
    369   EXPECT_EQ(O_RDONLY, fcntl(handle_fd, F_GETFL) & O_ACCMODE)
    370       << "The descriptor itself should be read-only.";
    371 
    372   errno = 0;
    373   void* writable = mmap(NULL, contents.size(), PROT_READ | PROT_WRITE,
    374                         MAP_SHARED, handle_fd, 0);
    375   int mmap_errno = errno;
    376   EXPECT_EQ(MAP_FAILED, writable)
    377       << "It shouldn't be possible to re-mmap the descriptor writable.";
    378   EXPECT_EQ(EACCES, mmap_errno) << strerror(mmap_errno);
    379   if (writable != MAP_FAILED)
    380     EXPECT_EQ(0, munmap(writable, readonly_shmem.mapped_size()));
    381 
    382 #elif defined(OS_WIN)
    383   EXPECT_EQ(NULL, MapViewOfFile(handle.GetHandle(), FILE_MAP_WRITE, 0, 0, 0))
    384       << "Shouldn't be able to map memory writable.";
    385 
    386   HANDLE temp_handle;
    387   BOOL rv = ::DuplicateHandle(GetCurrentProcess(), handle.GetHandle(),
    388                               GetCurrentProcess(), &temp_handle,
    389                               FILE_MAP_ALL_ACCESS, false, 0);
    390   EXPECT_EQ(FALSE, rv)
    391       << "Shouldn't be able to duplicate the handle into a writable one.";
    392   if (rv)
    393     win::ScopedHandle writable_handle(temp_handle);
    394   rv = ::DuplicateHandle(GetCurrentProcess(), handle.GetHandle(),
    395                          GetCurrentProcess(), &temp_handle, FILE_MAP_READ,
    396                          false, 0);
    397   EXPECT_EQ(TRUE, rv)
    398       << "Should be able to duplicate the handle into a readable one.";
    399   if (rv)
    400     win::ScopedHandle writable_handle(temp_handle);
    401 #else
    402 #error Unexpected platform; write a test that tries to make 'handle' writable.
    403 #endif  // defined(OS_POSIX) || defined(OS_WIN)
    404 }
    405 
    406 TEST(SharedMemoryTest, ShareToSelf) {
    407   StringPiece contents = "Hello World";
    408 
    409   SharedMemory shmem;
    410   ASSERT_TRUE(shmem.CreateAndMapAnonymous(contents.size()));
    411   memcpy(shmem.memory(), contents.data(), contents.size());
    412   EXPECT_TRUE(shmem.Unmap());
    413 
    414   SharedMemoryHandle shared_handle;
    415   ASSERT_TRUE(shmem.ShareToProcess(GetCurrentProcessHandle(), &shared_handle));
    416 #if defined(OS_WIN)
    417   ASSERT_TRUE(shared_handle.OwnershipPassesToIPC());
    418 #endif
    419   SharedMemory shared(shared_handle, /*readonly=*/false);
    420 
    421   ASSERT_TRUE(shared.Map(contents.size()));
    422   EXPECT_EQ(
    423       contents,
    424       StringPiece(static_cast<const char*>(shared.memory()), contents.size()));
    425 
    426   shared_handle = SharedMemoryHandle();
    427   ASSERT_TRUE(shmem.ShareToProcess(GetCurrentProcessHandle(), &shared_handle));
    428 #if defined(OS_WIN)
    429   ASSERT_TRUE(shared_handle.OwnershipPassesToIPC());
    430 #endif
    431   SharedMemory readonly(shared_handle, /*readonly=*/true);
    432 
    433   ASSERT_TRUE(readonly.Map(contents.size()));
    434   EXPECT_EQ(contents,
    435             StringPiece(static_cast<const char*>(readonly.memory()),
    436                         contents.size()));
    437 }
    438 
    439 TEST(SharedMemoryTest, MapAt) {
    440   ASSERT_TRUE(SysInfo::VMAllocationGranularity() >= sizeof(uint32_t));
    441   const size_t kCount = SysInfo::VMAllocationGranularity();
    442   const size_t kDataSize = kCount * sizeof(uint32_t);
    443 
    444   SharedMemory memory;
    445   ASSERT_TRUE(memory.CreateAndMapAnonymous(kDataSize));
    446   uint32_t* ptr = static_cast<uint32_t*>(memory.memory());
    447   ASSERT_NE(ptr, static_cast<void*>(NULL));
    448 
    449   for (size_t i = 0; i < kCount; ++i) {
    450     ptr[i] = i;
    451   }
    452 
    453   memory.Unmap();
    454 
    455   off_t offset = SysInfo::VMAllocationGranularity();
    456   ASSERT_TRUE(memory.MapAt(offset, kDataSize - offset));
    457   offset /= sizeof(uint32_t);
    458   ptr = static_cast<uint32_t*>(memory.memory());
    459   ASSERT_NE(ptr, static_cast<void*>(NULL));
    460   for (size_t i = offset; i < kCount; ++i) {
    461     EXPECT_EQ(ptr[i - offset], i);
    462   }
    463 }
    464 
    465 TEST(SharedMemoryTest, MapTwice) {
    466   const uint32_t kDataSize = 1024;
    467   SharedMemory memory;
    468   bool rv = memory.CreateAndMapAnonymous(kDataSize);
    469   EXPECT_TRUE(rv);
    470 
    471   void* old_address = memory.memory();
    472 
    473   rv = memory.Map(kDataSize);
    474   EXPECT_FALSE(rv);
    475   EXPECT_EQ(old_address, memory.memory());
    476 }
    477 
    478 #if defined(OS_POSIX)
    479 // This test is not applicable for iOS (crbug.com/399384).
    480 #if !defined(OS_IOS)
    481 // Create a shared memory object, mmap it, and mprotect it to PROT_EXEC.
    482 TEST(SharedMemoryTest, AnonymousExecutable) {
    483   const uint32_t kTestSize = 1 << 16;
    484 
    485   SharedMemory shared_memory;
    486   SharedMemoryCreateOptions options;
    487   options.size = kTestSize;
    488   options.executable = true;
    489 #if defined(OS_MACOSX) && !defined(OS_IOS)
    490   // The Mach functionality is tested in shared_memory_mac_unittest.cc.
    491   options.type = SharedMemoryHandle::POSIX;
    492 #endif
    493 
    494   EXPECT_TRUE(shared_memory.Create(options));
    495   EXPECT_TRUE(shared_memory.Map(shared_memory.requested_size()));
    496 
    497   EXPECT_EQ(0, mprotect(shared_memory.memory(), shared_memory.requested_size(),
    498                         PROT_READ | PROT_EXEC));
    499 }
    500 #endif  // !defined(OS_IOS)
    501 
    502 // Android supports a different permission model than POSIX for its "ashmem"
    503 // shared memory implementation. So the tests about file permissions are not
    504 // included on Android.
    505 #if !defined(OS_ANDROID)
    506 
    507 // Set a umask and restore the old mask on destruction.
    508 class ScopedUmaskSetter {
    509  public:
    510   explicit ScopedUmaskSetter(mode_t target_mask) {
    511     old_umask_ = umask(target_mask);
    512   }
    513   ~ScopedUmaskSetter() { umask(old_umask_); }
    514  private:
    515   mode_t old_umask_;
    516   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedUmaskSetter);
    517 };
    518 
    519 // Create a shared memory object, check its permissions.
    520 TEST(SharedMemoryTest, FilePermissionsAnonymous) {
    521   const uint32_t kTestSize = 1 << 8;
    522 
    523   SharedMemory shared_memory;
    524   SharedMemoryCreateOptions options;
    525   options.size = kTestSize;
    526 #if defined(OS_MACOSX) && !defined(OS_IOS)
    527   // The Mach functionality is tested in shared_memory_mac_unittest.cc.
    528   options.type = SharedMemoryHandle::POSIX;
    529 #endif
    530   // Set a file mode creation mask that gives all permissions.
    531   ScopedUmaskSetter permissive_mask(S_IWGRP | S_IWOTH);
    532 
    533   EXPECT_TRUE(shared_memory.Create(options));
    534 
    535   int shm_fd =
    536       SharedMemory::GetFdFromSharedMemoryHandle(shared_memory.handle());
    537   struct stat shm_stat;
    538   EXPECT_EQ(0, fstat(shm_fd, &shm_stat));
    539   // Neither the group, nor others should be able to read the shared memory
    540   // file.
    541   EXPECT_FALSE(shm_stat.st_mode & S_IRWXO);
    542   EXPECT_FALSE(shm_stat.st_mode & S_IRWXG);
    543 }
    544 
    545 // Create a shared memory object, check its permissions.
    546 TEST(SharedMemoryTest, FilePermissionsNamed) {
    547   const uint32_t kTestSize = 1 << 8;
    548 
    549   SharedMemory shared_memory;
    550   SharedMemoryCreateOptions options;
    551   options.size = kTestSize;
    552 #if defined(OS_MACOSX) && !defined(OS_IOS)
    553   // The Mach functionality is tested in shared_memory_mac_unittest.cc.
    554   options.type = SharedMemoryHandle::POSIX;
    555 #endif
    556 
    557   // Set a file mode creation mask that gives all permissions.
    558   ScopedUmaskSetter permissive_mask(S_IWGRP | S_IWOTH);
    559 
    560   EXPECT_TRUE(shared_memory.Create(options));
    561 
    562   int fd = SharedMemory::GetFdFromSharedMemoryHandle(shared_memory.handle());
    563   struct stat shm_stat;
    564   EXPECT_EQ(0, fstat(fd, &shm_stat));
    565   // Neither the group, nor others should have been able to open the shared
    566   // memory file while its name existed.
    567   EXPECT_FALSE(shm_stat.st_mode & S_IRWXO);
    568   EXPECT_FALSE(shm_stat.st_mode & S_IRWXG);
    569 }
    570 #endif  // !defined(OS_ANDROID)
    571 
    572 #endif  // defined(OS_POSIX)
    573 
    574 // Map() will return addresses which are aligned to the platform page size, this
    575 // varies from platform to platform though.  Since we'd like to advertise a
    576 // minimum alignment that callers can count on, test for it here.
    577 TEST(SharedMemoryTest, MapMinimumAlignment) {
    578   static const int kDataSize = 8192;
    579 
    580   SharedMemory shared_memory;
    581   ASSERT_TRUE(shared_memory.CreateAndMapAnonymous(kDataSize));
    582   EXPECT_EQ(0U, reinterpret_cast<uintptr_t>(
    583       shared_memory.memory()) & (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1));
    584   shared_memory.Close();
    585 }
    586 
    587 #if defined(OS_WIN)
    588 TEST(SharedMemoryTest, UnsafeImageSection) {
    589   const char kTestSectionName[] = "UnsafeImageSection";
    590   wchar_t path[MAX_PATH];
    591   EXPECT_GT(::GetModuleFileName(nullptr, path, arraysize(path)), 0U);
    592 
    593   // Map the current executable image to save us creating a new PE file on disk.
    594   base::win::ScopedHandle file_handle(::CreateFile(
    595       path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr));
    596   EXPECT_TRUE(file_handle.IsValid());
    597   base::win::ScopedHandle section_handle(
    598       ::CreateFileMappingA(file_handle.Get(), nullptr,
    599                            PAGE_READONLY | SEC_IMAGE, 0, 0, kTestSectionName));
    600   EXPECT_TRUE(section_handle.IsValid());
    601 
    602   // Check direct opening by name, from handle and duplicated from handle.
    603   SharedMemory shared_memory_open;
    604   EXPECT_TRUE(shared_memory_open.Open(kTestSectionName, true));
    605   EXPECT_FALSE(shared_memory_open.Map(1));
    606   EXPECT_EQ(nullptr, shared_memory_open.memory());
    607 
    608   SharedMemory shared_memory_handle_local(
    609       SharedMemoryHandle(section_handle.Take(), ::GetCurrentProcessId()), true);
    610   EXPECT_FALSE(shared_memory_handle_local.Map(1));
    611   EXPECT_EQ(nullptr, shared_memory_handle_local.memory());
    612 
    613   // Check that a handle without SECTION_QUERY also can't be mapped as it can't
    614   // be checked.
    615   SharedMemory shared_memory_handle_dummy;
    616   SharedMemoryCreateOptions options;
    617   options.size = 0x1000;
    618   EXPECT_TRUE(shared_memory_handle_dummy.Create(options));
    619   HANDLE handle_no_query;
    620   EXPECT_TRUE(::DuplicateHandle(
    621       ::GetCurrentProcess(), shared_memory_handle_dummy.handle().GetHandle(),
    622       ::GetCurrentProcess(), &handle_no_query, FILE_MAP_READ, FALSE, 0));
    623   SharedMemory shared_memory_handle_no_query(
    624       SharedMemoryHandle(handle_no_query, ::GetCurrentProcessId()), true);
    625   EXPECT_FALSE(shared_memory_handle_no_query.Map(1));
    626   EXPECT_EQ(nullptr, shared_memory_handle_no_query.memory());
    627 }
    628 #endif  // defined(OS_WIN)
    629 
    630 // iOS does not allow multiple processes.
    631 // Android ashmem does not support named shared memory.
    632 // Mac SharedMemory does not support named shared memory. crbug.com/345734
    633 #if !defined(OS_IOS) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
    634 // On POSIX it is especially important we test shmem across processes,
    635 // not just across threads.  But the test is enabled on all platforms.
    636 class SharedMemoryProcessTest : public MultiProcessTest {
    637  public:
    638   static void CleanUp() {
    639     SharedMemory memory;
    640     memory.Delete(s_test_name_);
    641   }
    642 
    643   static int TaskTestMain() {
    644     int errors = 0;
    645     SharedMemory memory;
    646     bool rv = memory.CreateNamedDeprecated(s_test_name_, true, s_data_size_);
    647     EXPECT_TRUE(rv);
    648     if (rv != true)
    649       errors++;
    650     rv = memory.Map(s_data_size_);
    651     EXPECT_TRUE(rv);
    652     if (rv != true)
    653       errors++;
    654     int* ptr = static_cast<int*>(memory.memory());
    655 
    656     // This runs concurrently in multiple processes. Writes need to be atomic.
    657     subtle::Barrier_AtomicIncrement(ptr, 1);
    658     memory.Close();
    659     return errors;
    660   }
    661 
    662   static const char s_test_name_[];
    663   static const uint32_t s_data_size_;
    664 };
    665 
    666 const char SharedMemoryProcessTest::s_test_name_[] = "MPMem";
    667 const uint32_t SharedMemoryProcessTest::s_data_size_ = 1024;
    668 
    669 TEST_F(SharedMemoryProcessTest, SharedMemoryAcrossProcesses) {
    670   const int kNumTasks = 5;
    671 
    672   SharedMemoryProcessTest::CleanUp();
    673 
    674   // Create a shared memory region. Set the first word to 0.
    675   SharedMemory memory;
    676   bool rv = memory.CreateNamedDeprecated(s_test_name_, true, s_data_size_);
    677   ASSERT_TRUE(rv);
    678   rv = memory.Map(s_data_size_);
    679   ASSERT_TRUE(rv);
    680   int* ptr = static_cast<int*>(memory.memory());
    681   *ptr = 0;
    682 
    683   // Start |kNumTasks| processes, each of which atomically increments the first
    684   // word by 1.
    685   SpawnChildResult children[kNumTasks];
    686   for (int index = 0; index < kNumTasks; ++index) {
    687     children[index] = SpawnChild("SharedMemoryTestMain");
    688     ASSERT_TRUE(children[index].process.IsValid());
    689   }
    690 
    691   // Check that each process exited correctly.
    692   int exit_code = 0;
    693   for (int index = 0; index < kNumTasks; ++index) {
    694     EXPECT_TRUE(children[index].process.WaitForExit(&exit_code));
    695     EXPECT_EQ(0, exit_code);
    696   }
    697 
    698   // Check that the shared memory region reflects |kNumTasks| increments.
    699   ASSERT_EQ(kNumTasks, *ptr);
    700 
    701   memory.Close();
    702   SharedMemoryProcessTest::CleanUp();
    703 }
    704 
    705 MULTIPROCESS_TEST_MAIN(SharedMemoryTestMain) {
    706   return SharedMemoryProcessTest::TaskTestMain();
    707 }
    708 #endif  // !defined(OS_IOS) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
    709 
    710 }  // namespace base
    711