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

Unified Diff: content/test/content_android_linker_unittest.cc

Issue 23717023: Android: Add chrome-specific dynamic linker. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase to fix build. Created 7 years, 3 months 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
Index: content/test/content_android_linker_unittest.cc
diff --git a/content/test/content_android_linker_unittest.cc b/content/test/content_android_linker_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..aaab0f9b82621366e7ca70b0cc3d2554188158dc
--- /dev/null
+++ b/content/test/content_android_linker_unittest.cc
@@ -0,0 +1,129 @@
+// Copyright (c) 2013 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.
+
+#ifndef CONTENT_TEST_CONTENT_LINKER_UNITTEST_H
+#define CONTENT_TEST_CONTENT_LINKER_UNITTEST_H
+
+#include <errno.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/debug/proc_maps_linux.h"
+#include "base/strings/stringprintf.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+// The RELRO section(s), after being copied into an ashmem region, will
+// appear in /proc/self/maps as a mapped memory region for a file name
+// that begins with the following prefix.
+//
+// Note that the full name will be something like:
+// "/dev/ashmem/RELRO:<libname> (deleted)"
+//
+// Where <libname> is the library name and '(deleted)' is actually
+// added by the kernel to indicate there is no corresponding file
+// on the filesystem.
+//
+// For regular builds, there is only one library, and thus one RELRO
+// section, but for the component build, there are several libraries,
+// each one with its own RELRO.
+static const char kRelroSectionPrefix[] = "/dev/ashmem/RELRO:";
+
+using base::debug::MappedMemoryRegion;
+
+class ContentLinkerTest : public ::testing::Test {
+ public:
+ ContentLinkerTest()
+ : regions_(), relro_section_prefix_(kRelroSectionPrefix) {}
+
+ protected:
+ virtual void SetUp() {
+ regions_.clear();
+ std::string maps;
+ base::debug::ReadProcMaps(&maps);
+ base::debug::ParseProcMaps(maps, &regions_);
+ }
+
+ virtual void TearDown() {}
+
+ std::vector<MappedMemoryRegion> regions_;
+ std::string relro_section_prefix_;
+};
+
+} // namespace
+
+// This test checks that our content-based library has been loaded
+// and that its RELRO section is in an ashmem region, with a name
+// that begins with /dev/ashmem/RELRO:
+//
+TEST_F(ContentLinkerTest, RelroInAshmem) {
+ size_t count = 0;
+
+ for (size_t n = 0; n < regions_.size(); ++n) {
+ MappedMemoryRegion& region = regions_[n];
+
+ if (region.path.find(relro_section_prefix_) == 0)
+ count++;
+ }
+
+ // Can't use EXPECT_EQ here due to the component build having
+ // many libraries loaded through our linker, each one with its own
+ // shared RELRO section. There are also plenty of system libraries
+ // without a shared RELRO section as well.
+ EXPECT_GE(count, 1U)
+ << "The number of RELRO sections in ashmem regions in this process\n";
+}
+
+// This test checks that every shared RELRO section is always read-only
+// and non-executable.
+TEST_F(ContentLinkerTest, RelroIsReadOnly) {
+ uint8 expected_flags = MappedMemoryRegion::READ;
+ uint8 expected_mask = MappedMemoryRegion::READ | MappedMemoryRegion::WRITE |
+ MappedMemoryRegion::EXECUTE;
+
+ for (size_t n = 0; n < regions_.size(); ++n) {
+ MappedMemoryRegion& region = regions_[n];
+
+ if (region.path.find(relro_section_prefix_) != 0)
+ continue;
+
+ EXPECT_EQ(expected_flags, region.permissions & expected_mask)
+ << base::StringPrintf(
+ "Checking permissions for RELRO region at %p-%p\n",
+ reinterpret_cast<void*>(region.start),
+ reinterpret_cast<void*>(region.end));
+ }
+}
+
+// This test checks that each RELRO section cannot be remapped read-write
+// with mprotect(), for security reasons.
+TEST_F(ContentLinkerTest, RelroCantBeRemappedWritable) {
+ for (size_t n = 0; n < regions_.size(); ++n) {
+ MappedMemoryRegion& region = regions_[n];
+
+ if (region.path.find(relro_section_prefix_) != 0)
+ continue;
+
+ std::string text = base::StringPrintf(
+ "Checking non-writability for RELRO region at %p-%p\n",
+ reinterpret_cast<void*>(region.start),
+ reinterpret_cast<void*>(region.end));
+
+ EXPECT_EQ(-1,
+ ::mprotect(reinterpret_cast<void*>(region.start),
+ region.end - region.start,
+ PROT_READ | PROT_WRITE))
+ << text;
+ EXPECT_EQ(EACCES, errno) << text;
+ }
+}
+
+} // namespace content
+
+#endif // CONTENT_TEST_CONTENT_LINKER_UNITTEST_H

Powered by Google App Engine
This is Rietveld 408576698