summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sandbox/linux/seccomp/library.h21
-rw-r--r--sandbox/linux/seccomp/maps.h3
-rw-r--r--third_party/tcmalloc/chromium/src/base/spinlock_linux-inl.h20
3 files changed, 34 insertions, 10 deletions
diff --git a/sandbox/linux/seccomp/library.h b/sandbox/linux/seccomp/library.h
index 29a755e..96ec581 100644
--- a/sandbox/linux/seccomp/library.h
+++ b/sandbox/linux/seccomp/library.h
@@ -6,6 +6,7 @@
#define LIBRARY_H__
#include <elf.h>
+#include <functional>
#include <map>
#include <set>
#include <string>
@@ -135,6 +136,9 @@ class Library {
private:
class GreaterThan : public std::binary_function<Elf_Addr, Elf_Addr, bool> {
+ // We create the RangeMap with a GreaterThan rather than the default
+ // comparator, as that allows us to use lower_bound() to find memory
+ // mappings.
public:
bool operator() (Elf_Addr s1, Elf_Addr s2) const {
return s1 > s2;
@@ -149,10 +153,19 @@ class Library {
int prot;
};
- typedef std::map<Elf_Addr, Range, GreaterThan> RangeMap;
- typedef std::map<string, std::pair<int, Elf_Shdr> > SectionTable;
- typedef std::map<string, Elf_Sym> SymbolTable;
- typedef std::map<string, Elf_Addr> PltTable;
+ typedef std::map<Elf_Addr, Range, GreaterThan,
+ SystemAllocator<std::pair<const Elf_Addr,
+ Range> > > RangeMap;
+ typedef std::map<string, std::pair<int, Elf_Shdr>, std::less<string>,
+ SystemAllocator<std::pair<const string,
+ std::pair<int, Elf_Shdr> > > >
+ SectionTable;
+ typedef std::map<string, Elf_Sym, std::less<string>,
+ SystemAllocator<std::pair<const string,
+ Elf_Sym> > > SymbolTable;
+ typedef std::map<string, Elf_Addr, std::less<string>,
+ SystemAllocator<std::pair<const string,
+ Elf_Addr> > > PltTable;
char* getBytes(char* dst, const char* src, ssize_t len);
static bool isSafeInsn(unsigned short insn);
diff --git a/sandbox/linux/seccomp/maps.h b/sandbox/linux/seccomp/maps.h
index 5f51782..fbcc7672 100644
--- a/sandbox/linux/seccomp/maps.h
+++ b/sandbox/linux/seccomp/maps.h
@@ -37,7 +37,8 @@ class Maps {
// The key is a unique combination of device number, inode number, and
// file name. It should be treated as opaque.
typedef std::map<string, Library, std::less<string>,
- SystemAllocator<string> > LibraryMap;
+ SystemAllocator<std::pair<const string,
+ Library> > > LibraryMap;
friend class Iterator;
class Iterator {
friend class Maps;
diff --git a/third_party/tcmalloc/chromium/src/base/spinlock_linux-inl.h b/third_party/tcmalloc/chromium/src/base/spinlock_linux-inl.h
index 0df09a3..f7b4a41 100644
--- a/third_party/tcmalloc/chromium/src/base/spinlock_linux-inl.h
+++ b/third_party/tcmalloc/chromium/src/base/spinlock_linux-inl.h
@@ -33,12 +33,22 @@
#include <sched.h>
#include <time.h>
-#include "base/linux_syscall_support.h"
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define FUTEX_PRIVATE_FLAG 128
+// Note: Instead of making direct system calls that are inlined, we rely
+// on the syscall() function in glibc to do the right thing. This
+// is necessary to make the code compatible with the seccomp sandbox,
+// which needs to be able to find and patch all places where system
+// calls are made. Scanning through and patching glibc is fast, but
+// doing so on the entire Chrome binary would be prohibitively
+// expensive.
+// This is a notable change from the upstream version of tcmalloc,
+// which prefers direct system calls in order to improve compatibility
+// with older toolchains and runtime libraries.
+
static bool have_futex;
static int futex_private_flag = FUTEX_PRIVATE_FLAG;
@@ -49,9 +59,9 @@ static struct InitModule {
// futexes are ints, so we can use them only when
// that's the same size as the lockword_ in SpinLock.
have_futex = (sizeof (Atomic32) == sizeof (int) &&
- sys_futex(&x, FUTEX_WAKE, 1, 0) >= 0);
+ syscall(__NR_futex, &x, FUTEX_WAKE, 1, 0) >= 0);
if (have_futex &&
- sys_futex(&x, FUTEX_WAKE | futex_private_flag, 1, 0) < 0) {
+ syscall(__NR_futex, &x, FUTEX_WAKE | futex_private_flag, 1, 0) < 0) {
futex_private_flag = 0;
}
}
@@ -67,7 +77,7 @@ static void SpinLockWait(volatile Atomic32 *w) {
tm.tv_nsec = 1000000; // 1ms; really we're trying to sleep for one kernel
// clock tick
while ((value = base::subtle::Acquire_CompareAndSwap(w, 0, 1)) != 0) {
- sys_futex(reinterpret_cast<int *>(const_cast<Atomic32 *>(w)),
+ syscall(__NR_futex, reinterpret_cast<int *>(const_cast<Atomic32 *>(w)),
FUTEX_WAIT | futex_private_flag,
value, reinterpret_cast<struct kernel_timespec *>(&tm));
}
@@ -85,7 +95,7 @@ static void SpinLockWait(volatile Atomic32 *w) {
static void SpinLockWake(volatile Atomic32 *w) {
if (have_futex) {
- sys_futex(reinterpret_cast<int *>(const_cast<Atomic32 *>(w)),
+ syscall(__NR_futex, reinterpret_cast<int *>(const_cast<Atomic32 *>(w)),
FUTEX_WAKE | futex_private_flag, 1, 0);
}
}