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

Unified Diff: sandbox/linux/seccomp/syscall.cc

Issue 661438: Seccomp sandbox changes (performance and correctness fixes, primarily targetting x86-32) (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 10 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
« no previous file with comments | « sandbox/linux/seccomp/securemem.h ('k') | sandbox/linux/seccomp/trusted_thread.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sandbox/linux/seccomp/syscall.cc
===================================================================
--- sandbox/linux/seccomp/syscall.cc (revision 39965)
+++ sandbox/linux/seccomp/syscall.cc (working copy)
@@ -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.
+
#include "debug.h"
#include "sandbox_impl.h"
#include "syscall_table.h"
@@ -146,14 +150,76 @@
// Check range of system call
"cmp playground$maxSyscall, %eax\n"
- "ja 1f\n"
+ "ja 5f\n"
+ // We often have long sequences of calls to gettimeofday(). This is
+ // needlessly expensive. Coalesce them into a single call.
+ //
+ // We keep track of state in TLS storage that we can access through
+ // the %fs segment register. See trusted_thread.cc for the exact
+ // memory layout.
+ //
+ // TODO(markus): maybe, we should proactively call gettimeofday() and
+ // clock_gettime(), whenever we talk to the trusted thread?
+ // or maybe, if we have recently seen requests to compute
+ // the time. There might be a repeated pattern of those.
+ "cmp $78, %eax\n" // __NR_gettimeofday
+ "jnz 2f\n"
+ "cmp %eax, %fs:0x102C-0x54\n" // last system call
+ "jnz 0f\n"
+
+ // This system call and the last system call prior to this one both are
+ // calls to gettimeofday(). Try to avoid making the new call and just
+ // return the same result as in the previous call.
+ // Just in case the caller is spinning on the result from gettimeofday(),
+ // every so often, call the actual system call.
+ "decl %fs:0x1030-0x54\n" // countdown calls to gettimofday()
+ "jz 0f\n"
+
+ // Atomically read the 64bit word representing last-known timestamp and
+ // return it to the caller. On x86-32 this is a little more complicated and
+ // requires the use of the cmpxchg8b instruction.
+ "mov %ebx, %eax\n"
+ "mov %ecx, %edx\n"
+ "lock; cmpxchg8b 100f\n"
+ "mov %eax, 0(%ebx)\n"
+ "mov %edx, 4(%ebx)\n"
+ "xor %eax, %eax\n"
+ "add $28, %esp\n"
+ "jmp 4f\n"
+
+ // This is a call to gettimeofday(), but we don't have a valid cached
+ // result, yet.
+ "0:mov %eax, %fs:0x102C-0x54\n" // remember syscall number
+ "movl $500, %fs:0x1030-0x54\n" // make system call, each 500 invocations
+ "call playground$defaultSystemCallHandler\n"
+
+ // Returned from gettimeofday(). Remember return value, in case the
+ // application calls us again right away.
+ // Again, this has to happen atomically and requires cmpxchg8b.
+ "mov 4(%ebx), %ecx\n"
+ "mov 0(%ebx), %ebx\n"
+ "mov 100f, %eax\n"
+ "mov 101f, %edx\n"
+ "1:lock; cmpxchg8b 100f\n"
+ "jnz 1b\n"
+ "xor %eax, %eax\n"
+ "jmp 6f\n"
+
+ // Remember the number of the last system call made. We deliberately do
+ // not remember calls to gettid(), as we have often seen long sequences
+ // of calls to just gettimeofday() and gettid(). In that situation, we
+ // would still like to coalesce the gettimeofday() calls.
+ "2:cmp $224, %eax\n" // __NR_gettid
+ "jz 3f\n"
+ "mov %eax, %fs:0x102C-0x54\n" // remember syscall number
+
// Retrieve function call from system call table (c.f. syscall_table.c).
// We have three different types of entries; zero for denied system calls,
// that should be handled by the defaultSystemCallHandler(); minus one
// for unrestricted system calls that need to be forwarded to the trusted
// thread; and function pointers to specific handler functions.
- "shl $3, %eax\n"
+ "3:shl $3, %eax\n"
"lea playground$syscallTable, %ebx\n"
"add %ebx, %eax\n"
"mov 0(%eax), %eax\n"
@@ -161,14 +227,13 @@
// Jump to function if non-null and not UNRESTRICTED_SYSCALL, otherwise
// jump to fallback handler.
"cmp $1, %eax\n"
- "jbe 1f\n"
+ "jbe 5f\n"
"add $4, %esp\n"
"call *%eax\n"
"add $24, %esp\n"
- "0:"
// Restore CPU registers, except for %eax which was set by the system call.
- "pop %ebp\n"
+ "4:pop %ebp\n"
"pop %edi\n"
"pop %esi\n"
"pop %edx\n"
@@ -178,14 +243,17 @@
// Return to caller
"ret\n"
- "1:"
// Call default handler.
- "push $2f\n"
- "push $playground$defaultSystemCallHandler\n"
- "ret\n"
- "2:add $28, %esp\n"
- "jmp 0b\n"
+ "5:call playground$defaultSystemCallHandler\n"
+ "6:add $28, %esp\n"
+ "jmp 4b\n"
+ ".pushsection \".bss\"\n"
+ ".balign 8\n"
+"100:.byte 0, 0, 0, 0\n"
+"101:.byte 0, 0, 0, 0\n"
+ ".popsection\n"
+
#else
#error Unsupported target platform
#endif
« no previous file with comments | « sandbox/linux/seccomp/securemem.h ('k') | sandbox/linux/seccomp/trusted_thread.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698