diff options
author | markus@chromium.org <markus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-08 17:06:40 +0000 |
---|---|---|
committer | markus@chromium.org <markus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-08 17:06:40 +0000 |
commit | 9c856aad878f62b8517c74546455bd9909e055d3 (patch) | |
tree | 4897ec23fa996c543b1e415f8af5be0572031e28 /sandbox/linux/seccomp/library.h | |
parent | 668c911c24e6ddef75a7ee6578da11b0055b1f16 (diff) | |
download | chromium_src-9c856aad878f62b8517c74546455bd9909e055d3.zip chromium_src-9c856aad878f62b8517c74546455bd9909e055d3.tar.gz chromium_src-9c856aad878f62b8517c74546455bd9909e055d3.tar.bz2 |
- Add a custom allocator for STL objects. This fixes sandbox failures that
were observed on some machines (in particular in 32bit mode).
- Some more changes to avoid calling into glibc when we can make a direct
system call, instead. These particular call sites were unlikely to cause
any problems. But it makes the code easier to audit if we avoid all
unnecessary calls into glibc.
- In 64bit mode, gettimeofday() is handled by vsyscalls and tends to be cheap.
In 32bit mode, it is just a regular system call. Some users rely on being
able to call gettimeofday() at a very high rate (up to thousands of
consecutive calls). Recognize this system call pattern and optimize for it.
- Add debugging option that allows us to warn about expensive system calls.
In many cases, these warnings can then be used to optimize the sandboxed
application.
- Fix compilation on newer versions of gcc.
- Changed the x86-32 version of the code that we use when intercepting
system calls. Previously, we would use CALL to jump to the set of
instructions that we had relocated. But we made the mistake of allowing
relocation of instructions that reference %esp. This doesn't work, as
CALL modifies the stack. We now avoid using CALL and instead jump
directly. On x86-32 that requires the use of a PUSH/RET combination as
there is no 32bit wide JMP instruction.
The x86-64 version of the code was already written in a way that would
avoid this particular problem.
(I would like to thank Craig Schlenter for his exceptional detective
work in tracking down the root cause of this bug!)
- For debugging purposes, injected a really small library (less than 4kB)
and discovered that some of our memory map manipulations implicitly
relied on mappings to be at least two pages long. Fixed the code that
made this incorrect assumption.
- For really small libraries, the runtime linker can choose a different
more compact layout. Our computation of the ASR offset did not know how
to deal with that. Fixed by explicitly looking for a ".text" segment
instead of looking for a PT_DYNAMIC section.
- Closed a file descriptor that we kept open longer than needed.
- Removed some unused code.
- Added copyright headers
TEST=tested on i386 and x86-64
BUG=36133
Review URL: http://codereview.chromium.org/661438
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40900 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/linux/seccomp/library.h')
-rw-r--r-- | sandbox/linux/seccomp/library.h | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/sandbox/linux/seccomp/library.h b/sandbox/linux/seccomp/library.h index 523652c..29a755e 100644 --- a/sandbox/linux/seccomp/library.h +++ b/sandbox/linux/seccomp/library.h @@ -1,3 +1,7 @@ +// Copyright (c) 2010 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 LIBRARY_H__ #define LIBRARY_H__ @@ -30,6 +34,8 @@ namespace playground { class Library { friend class Maps; public: + typedef Maps::string string; + Library() : valid_(false), isVDSO_(false), @@ -50,14 +56,24 @@ class Library { void addMemoryRange(void* start, void* stop, Elf_Addr offset, int prot, int isVDSO) { - memory_ranges_.insert(std::make_pair(offset, Range(start, stop, prot))); isVDSO_ = isVDSO; + RangeMap::const_iterator iter = memory_ranges_.find(offset); + if (iter != memory_ranges_.end()) { + // It is possible to have overlapping mappings. This is particularly + // likely to happen with very small programs or libraries. If it does + // happen, we really only care about the text segment. Look for a + // mapping that is mapped executable. + if ((prot & PROT_EXEC) == 0) { + return; + } + } + memory_ranges_.insert(std::make_pair(offset, Range(start, stop, prot))); } char *get(Elf_Addr offset, char *buf, size_t len); - std::string get(Elf_Addr offset); + string get(Elf_Addr offset); char *getOriginal(Elf_Addr offset, char *buf, size_t len); - std::string getOriginal(Elf_Addr offset); + string getOriginal(Elf_Addr offset); template<class T>T* get(Elf_Addr offset, T* t) { if (!valid_) { @@ -108,10 +124,8 @@ class Library { bool parseElf(); const Elf_Ehdr* getEhdr(); - const Elf_Shdr* getSection(const std::string& section); - const int getSectionIndex(const std::string& section); - void **getRelocation(const std::string& symbol); - void *getSymbol(const std::string& symbol); + const Elf_Shdr* getSection(const string& section); + const int getSectionIndex(const string& section); void makeWritable(bool state) const; void patchSystemCalls(); bool isVDSO() const { return isVDSO_; } @@ -136,9 +150,9 @@ class Library { }; typedef std::map<Elf_Addr, Range, GreaterThan> RangeMap; - typedef std::map<std::string, std::pair<int, Elf_Shdr> > SectionTable; - typedef std::map<std::string, Elf_Sym> SymbolTable; - typedef std::map<std::string, Elf_Addr> PltTable; + typedef std::map<string, std::pair<int, Elf_Shdr> > SectionTable; + typedef std::map<string, Elf_Sym> SymbolTable; + typedef std::map<string, Elf_Addr> PltTable; char* getBytes(char* dst, const char* src, ssize_t len); static bool isSafeInsn(unsigned short insn); |