Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(329)

Unified Diff: base/memory/shared_memory_unittest.cc

Issue 27265002: Implement SharedMemory::NewAnonymousReadOnly(contents). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix Mark's comments Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/memory/shared_memory_posix.cc ('k') | base/memory/shared_memory_win.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/memory/shared_memory_unittest.cc
diff --git a/base/memory/shared_memory_unittest.cc b/base/memory/shared_memory_unittest.cc
index a8dea8d4735186025e764a371cbe5fafc9103cbc..2b3ad7a4024a483a38a2ee020f3ea511636bb4b6 100644
--- a/base/memory/shared_memory_unittest.cc
+++ b/base/memory/shared_memory_unittest.cc
@@ -20,12 +20,18 @@
#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_WIN)
+#include "base/win/scoped_handle.h"
+#endif
+
static const int kNumThreads = 5;
static const int kNumTasks = 5;
@@ -361,6 +367,79 @@ TEST(SharedMemoryTest, AnonymousPrivate) {
}
}
+TEST(SharedMemoryTest, ShareReadOnly) {
+ StringPiece contents = "Hello World";
+
+ SharedMemory writable_shmem;
+ ASSERT_TRUE(writable_shmem.CreateAndMapAnonymous(contents.size()));
+ memcpy(writable_shmem.memory(), contents.data(), contents.size());
+ EXPECT_TRUE(writable_shmem.Unmap());
+
+ SharedMemoryHandle readonly_handle;
+ ASSERT_TRUE(writable_shmem.ShareReadOnlyToProcess(GetCurrentProcessHandle(),
+ &readonly_handle));
+ 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());
+
+ // 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()));
+
+ // 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_POSIX)
+ EXPECT_EQ(O_RDONLY, fcntl(handle.fd, F_GETFL) & O_ACCMODE)
+ << "The descriptor itself should be read-only.";
+
+ errno = 0;
+ void* writable = mmap(
+ NULL, 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, FILE_MAP_WRITE, 0, 0, 0))
+ << "Shouldn't be able to map memory writable.";
+
+ base::win::ScopedHandle writable_handle;
+ EXPECT_EQ(0,
+ ::DuplicateHandle(GetCurrentProcess(),
+ handle,
+ GetCurrentProcess,
+ writable_handle.Receive(),
+ FILE_MAP_ALL_ACCESS,
+ false,
+ 0))
+ << "Shouldn't be able to duplicate the handle into a writable one.";
+#else
+#error Unexpected platform; write a test that tries to make 'handle' writable.
+#endif // defined(OS_POSIX) || defined(OS_WIN)
+}
+
TEST(SharedMemoryTest, ShareToSelf) {
StringPiece contents = "Hello World";
@@ -377,6 +456,14 @@ TEST(SharedMemoryTest, ShareToSelf) {
EXPECT_EQ(
contents,
StringPiece(static_cast<const char*>(shared.memory()), contents.size()));
+
+ ASSERT_TRUE(shmem.ShareToProcess(GetCurrentProcessHandle(), &shared_handle));
+ 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(SharedMemoryTest, MapAt) {
« no previous file with comments | « base/memory/shared_memory_posix.cc ('k') | base/memory/shared_memory_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698