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

Side by Side Diff: base/process/launch_posix.cc

Issue 1176413003: Build ForkWithFlags and part of NamespaceSandbox under nonsfi newlib. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More comments. Created 5 years, 6 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 unified diff | Download patch
« no previous file with comments | « base/process/launch.h ('k') | sandbox/linux/services/namespace_sandbox.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/process/launch.h" 5 #include "base/process/launch.h"
6 6
7 #include <dirent.h> 7 #include <dirent.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <fcntl.h> 9 #include <fcntl.h>
10 #include <sched.h> 10 #include <sched.h>
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 58
59 #if defined(OS_MACOSX) 59 #if defined(OS_MACOSX)
60 #include <crt_externs.h> 60 #include <crt_externs.h>
61 #include <sys/event.h> 61 #include <sys/event.h>
62 #else 62 #else
63 extern char** environ; 63 extern char** environ;
64 #endif 64 #endif
65 65
66 namespace base { 66 namespace base {
67 67
68 #if !defined(OS_NACL_NONSFI)
69
68 namespace { 70 namespace {
69 71
70 // Get the process's "environment" (i.e. the thing that setenv/getenv 72 // Get the process's "environment" (i.e. the thing that setenv/getenv
71 // work with). 73 // work with).
72 char** GetEnvironment() { 74 char** GetEnvironment() {
73 #if defined(OS_MACOSX) 75 #if defined(OS_MACOSX)
74 return *_NSGetEnviron(); 76 return *_NSGetEnviron();
75 #else 77 #else
76 return environ; 78 return environ;
77 #endif 79 #endif
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 #if !defined(NDEBUG) 183 #if !defined(NDEBUG)
182 // Now ask the kernel again and check that no restorer will leak. 184 // Now ask the kernel again and check that no restorer will leak.
183 if (sys_rt_sigaction(signum, NULL, &act) || act.k_sa_restorer) { 185 if (sys_rt_sigaction(signum, NULL, &act) || act.k_sa_restorer) {
184 RAW_LOG(FATAL, "Cound not fix sa_restorer."); 186 RAW_LOG(FATAL, "Cound not fix sa_restorer.");
185 } 187 }
186 #endif // !defined(NDEBUG) 188 #endif // !defined(NDEBUG)
187 } 189 }
188 } 190 }
189 #endif // !defined(OS_LINUX) || 191 #endif // !defined(OS_LINUX) ||
190 // (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__)) 192 // (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__))
191
192 #if defined(OS_LINUX)
193 bool IsRunningOnValgrind() {
194 return RUNNING_ON_VALGRIND;
195 }
196
197 // This function runs on the stack specified on the clone call. It uses longjmp
198 // to switch back to the original stack so the child can return from sys_clone.
199 int CloneHelper(void* arg) {
200 jmp_buf* env_ptr = reinterpret_cast<jmp_buf*>(arg);
201 longjmp(*env_ptr, 1);
202
203 // Should not be reached.
204 RAW_CHECK(false);
205 return 1;
206 }
207
208 // This function is noinline to ensure that stack_buf is below the stack pointer
209 // that is saved when setjmp is called below. This is needed because when
210 // compiled with FORTIFY_SOURCE, glibc's longjmp checks that the stack is moved
211 // upwards. See crbug.com/442912 for more details.
212 #if defined(ADDRESS_SANITIZER)
213 // Disable AddressSanitizer instrumentation for this function to make sure
214 // |stack_buf| is allocated on thread stack instead of ASan's fake stack.
215 // Under ASan longjmp() will attempt to clean up the area between the old and
216 // new stack pointers and print a warning that may confuse the user.
217 __attribute__((no_sanitize_address))
218 #endif
219 NOINLINE pid_t CloneAndLongjmpInChild(unsigned long flags,
220 pid_t* ptid,
221 pid_t* ctid,
222 jmp_buf* env) {
223 // We use the libc clone wrapper instead of making the syscall
224 // directly because making the syscall may fail to update the libc's
225 // internal pid cache. The libc interface unfortunately requires
226 // specifying a new stack, so we use setjmp/longjmp to emulate
227 // fork-like behavior.
228 char stack_buf[PTHREAD_STACK_MIN];
229 #if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY) || \
230 defined(ARCH_CPU_MIPS64_FAMILY) || defined(ARCH_CPU_MIPS_FAMILY)
231 // The stack grows downward.
232 void* stack = stack_buf + sizeof(stack_buf);
233 #else
234 #error "Unsupported architecture"
235 #endif
236 return clone(&CloneHelper, stack, flags, env, ptid, nullptr, ctid);
237 }
238 #endif // defined(OS_LINUX)
239
240 } // anonymous namespace 193 } // anonymous namespace
241 194
242 // Functor for |ScopedDIR| (below). 195 // Functor for |ScopedDIR| (below).
243 struct ScopedDIRClose { 196 struct ScopedDIRClose {
244 inline void operator()(DIR* x) const { 197 inline void operator()(DIR* x) const {
245 if (x) 198 if (x)
246 closedir(x); 199 closedir(x);
247 } 200 }
248 }; 201 };
249 202
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 bool GetAppOutputWithExitCode(const CommandLine& cl, 687 bool GetAppOutputWithExitCode(const CommandLine& cl,
735 std::string* output, 688 std::string* output,
736 int* exit_code) { 689 int* exit_code) {
737 // Run |execve()| with the current environment and store "unlimited" data. 690 // Run |execve()| with the current environment and store "unlimited" data.
738 GetAppOutputInternalResult result = GetAppOutputInternal( 691 GetAppOutputInternalResult result = GetAppOutputInternal(
739 cl.argv(), NULL, output, std::numeric_limits<std::size_t>::max(), true, 692 cl.argv(), NULL, output, std::numeric_limits<std::size_t>::max(), true,
740 exit_code); 693 exit_code);
741 return result == EXECUTE_SUCCESS; 694 return result == EXECUTE_SUCCESS;
742 } 695 }
743 696
744 #if defined(OS_LINUX) 697 #endif // !defined(OS_NACL_NONSFI)
698
699 #if defined(OS_LINUX) || defined(OS_NACL_NONSFI)
700 namespace {
701
702 bool IsRunningOnValgrind() {
703 return RUNNING_ON_VALGRIND;
704 }
705
706 // This function runs on the stack specified on the clone call. It uses longjmp
707 // to switch back to the original stack so the child can return from sys_clone.
708 int CloneHelper(void* arg) {
709 jmp_buf* env_ptr = reinterpret_cast<jmp_buf*>(arg);
710 longjmp(*env_ptr, 1);
711
712 // Should not be reached.
713 RAW_CHECK(false);
714 return 1;
715 }
716
717 // This function is noinline to ensure that stack_buf is below the stack pointer
718 // that is saved when setjmp is called below. This is needed because when
719 // compiled with FORTIFY_SOURCE, glibc's longjmp checks that the stack is moved
720 // upwards. See crbug.com/442912 for more details.
721 #if defined(ADDRESS_SANITIZER)
722 // Disable AddressSanitizer instrumentation for this function to make sure
723 // |stack_buf| is allocated on thread stack instead of ASan's fake stack.
724 // Under ASan longjmp() will attempt to clean up the area between the old and
725 // new stack pointers and print a warning that may confuse the user.
726 __attribute__((no_sanitize_address))
727 #endif
728 NOINLINE pid_t CloneAndLongjmpInChild(unsigned long flags,
729 pid_t* ptid,
730 pid_t* ctid,
731 jmp_buf* env) {
732 // We use the libc clone wrapper instead of making the syscall
733 // directly because making the syscall may fail to update the libc's
734 // internal pid cache. The libc interface unfortunately requires
735 // specifying a new stack, so we use setjmp/longjmp to emulate
736 // fork-like behavior.
737 char stack_buf[PTHREAD_STACK_MIN];
738 #if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY) || \
739 defined(ARCH_CPU_MIPS64_FAMILY) || defined(ARCH_CPU_MIPS_FAMILY)
740 // The stack grows downward.
741 void* stack = stack_buf + sizeof(stack_buf);
742 #else
743 #error "Unsupported architecture"
744 #endif
745 return clone(&CloneHelper, stack, flags, env, ptid, nullptr, ctid);
746 }
747
748 } // anonymous namespace
749
745 pid_t ForkWithFlags(unsigned long flags, pid_t* ptid, pid_t* ctid) { 750 pid_t ForkWithFlags(unsigned long flags, pid_t* ptid, pid_t* ctid) {
746 const bool clone_tls_used = flags & CLONE_SETTLS; 751 const bool clone_tls_used = flags & CLONE_SETTLS;
747 const bool invalid_ctid = 752 const bool invalid_ctid =
748 (flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) && !ctid; 753 (flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) && !ctid;
749 const bool invalid_ptid = (flags & CLONE_PARENT_SETTID) && !ptid; 754 const bool invalid_ptid = (flags & CLONE_PARENT_SETTID) && !ptid;
750 755
751 // We do not support CLONE_VM. 756 // We do not support CLONE_VM.
752 const bool clone_vm_used = flags & CLONE_VM; 757 const bool clone_vm_used = flags & CLONE_VM;
753 758
754 if (clone_tls_used || invalid_ctid || invalid_ptid || clone_vm_used) { 759 if (clone_tls_used || invalid_ctid || invalid_ptid || clone_vm_used) {
(...skipping 18 matching lines...) Expand all
773 #endif 778 #endif
774 } 779 }
775 780
776 jmp_buf env; 781 jmp_buf env;
777 if (setjmp(env) == 0) { 782 if (setjmp(env) == 0) {
778 return CloneAndLongjmpInChild(flags, ptid, ctid, &env); 783 return CloneAndLongjmpInChild(flags, ptid, ctid, &env);
779 } 784 }
780 785
781 return 0; 786 return 0;
782 } 787 }
783 #endif // defined(OS_LINUX) 788 #endif // defined(OS_LINUX) || defined(OS_NACL_NONSFI)
784 789
785 } // namespace base 790 } // namespace base
OLDNEW
« no previous file with comments | « base/process/launch.h ('k') | sandbox/linux/services/namespace_sandbox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698