11From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
22From: David Greaves <david.greaves@jolla.com>
33Date: Wed, 20 Jan 2021 09:40:34 +0000
4- Subject: [PATCH] Provide ENV controls to bypass some sb2 calls between fork
5- exec
4+ Subject: [PATCH] Provide ENV controls to bypass some sb2 calls between
5+ fork exec
66
77In threaded systems there can be deadlocks caused by calling malloc
88after fork and before exec. Rust manages this but sb2 does not.
@@ -35,15 +35,15 @@ needed to support the SHIM functionality
3535Signed-off-by: David Greaves <david.greaves@jolla.com>
3636Signed-off-by: Ruben De Smet <ruben.de.smet@rubdos.be>
3737---
38- .../src/sys/unix/process/process_common.rs | 50 ++++++-
38+ .../src/sys/unix/process/process_common.rs | 55 ++++++-
3939 .../std/src/sys/unix/process/process_unix.rs | 138 ++++++++++++++++--
40- 2 files changed, 170 insertions(+), 18 deletions(-)
40+ 2 files changed, 173 insertions(+), 20 deletions(-)
4141
4242diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs
43- index 27bee714f5b4317132db508fe916c7e194d05bc5..7746177e0423b7689833cc84b6132240a8bb2bf0 100644
43+ index 640648e8707..f15625e0514 100644
4444--- a/library/std/src/sys/unix/process/process_common.rs
4545+++ b/library/std/src/sys/unix/process/process_common.rs
46- @@ -61 ,7 +61 ,7 @@ cfg_if::cfg_if! {
46+ @@ -84 ,7 +84 ,7 @@ pub unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::
4747 ////////////////////////////////////////////////////////////////////////////////
4848
4949 pub struct Command {
@@ -52,7 +52,7 @@ index 27bee714f5b4317132db508fe916c7e194d05bc5..7746177e0423b7689833cc84b6132240
5252 args: Vec<CString>,
5353 /// Exactly what will be passed to `execvp`.
5454 ///
55- @@ -70 ,6 +70 ,13 @@ pub struct Command {
55+ @@ -93 ,6 +93 ,13 @@ pub struct Command {
5656 /// `args` to properly update this as well.
5757 argv: Argv,
5858 env: CommandEnv,
@@ -64,9 +64,9 @@ index 27bee714f5b4317132db508fe916c7e194d05bc5..7746177e0423b7689833cc84b6132240
6464+ pub(crate) setgid: Option<SetgidFn>,
6565+ pub(crate) setgroups: Option<SetgroupsFn>,
6666
67+ program_kind: ProgramKind,
6768 cwd: Option<CString>,
68- uid: Option<uid_t>,
69- @@ -85,6 +92,14 @@ pub struct Command {
69+ @@ -109,6 +116,14 @@ pub struct Command {
7070 pgroup: Option<pid_t>,
7171 }
7272
@@ -81,18 +81,18 @@ index 27bee714f5b4317132db508fe916c7e194d05bc5..7746177e0423b7689833cc84b6132240
8181 // Create a new type for argv, so that we can make it `Send` and `Sync`
8282 struct Argv(Vec<*const c_char>);
8383
84- @@ -132,15 +147,23 @@ impl Command {
85- pub fn new(program: &OsStr) -> Command {
84+ @@ -181,16 +196,24 @@ pub fn new(program: &OsStr) -> Command {
8685 let mut saw_nul = false;
86+ let program_kind = ProgramKind::new(program.as_ref());
8787 let program = os2c(program, &mut saw_nul);
8888+ let arg0 = program.clone();
8989 Command {
9090- argv: Argv(vec![program.as_ptr(), ptr::null()]),
9191- args: vec![program.clone()],
92- - program,
9392+ argv: Argv(vec![arg0.as_ptr(), ptr::null()]),
9493+ args: vec![arg0],
95- + program: program,
94+ program,
95+ program_kind,
9696 env: Default::default(),
9797+ execvp: None,
9898+ dup2: None,
@@ -109,18 +109,18 @@ index 27bee714f5b4317132db508fe916c7e194d05bc5..7746177e0423b7689833cc84b6132240
109109 closures: Vec::new(),
110110 groups: None,
111111 stdin: None,
112- @@ -154,15 +177,23 @@ impl Command {
113- pub fn new(program: &OsStr) -> Command {
112+ @@ -205,16 +228,24 @@ pub fn new(program: &OsStr) -> Command {
114113 let mut saw_nul = false;
114+ let program_kind = ProgramKind::new(program.as_ref());
115115 let program = os2c(program, &mut saw_nul);
116116+ let arg0 = program.clone();
117117 Command {
118118- argv: Argv(vec![program.as_ptr(), ptr::null()]),
119119- args: vec![program.clone()],
120- - program,
121120+ argv: Argv(vec![arg0.as_ptr(), ptr::null()]),
122121+ args: vec![arg0],
123- + program: program,
122+ program,
123+ program_kind,
124124 env: Default::default(),
125125+ execvp: None,
126126+ dup2: None,
@@ -137,7 +137,7 @@ index 27bee714f5b4317132db508fe916c7e194d05bc5..7746177e0423b7689833cc84b6132240
137137 closures: Vec::new(),
138138 groups: None,
139139 stdin: None,
140- @@ -173 ,6 +204 ,16 @@ impl Command {
140+ @@ -225 ,6 +256 ,16 @@ pub fn new(program: &OsStr) -> Command {
141141 }
142142 }
143143
@@ -155,18 +155,21 @@ index 27bee714f5b4317132db508fe916c7e194d05bc5..7746177e0423b7689833cc84b6132240
155155 // Set a new arg0
156156 let arg = os2c(arg, &mut self.saw_nul);
157157diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs
158- index 3d305cd7310fd4b8419d220d1adeadebb9fda914..5d1c667b943cb2af0e0e918c17a7b24293617376 100644
158+ index 0ce93af66ac..04449d859bf 100644
159159--- a/library/std/src/sys/unix/process/process_unix.rs
160160+++ b/library/std/src/sys/unix/process/process_unix.rs
161- @@ -27,11 +27,15 @@
161+ @@ -28,7 +28,7 @@
162162 use libc::RTP_ID as pid_t;
163163
164164 #[cfg(not(target_os = "vxworks"))]
165165- use libc::{c_int, pid_t};
166166+ use libc::{c_char, c_int, dlsym, pid_t};
167167
168- #[cfg(not(any(target_os = "vxworks", target_os = "l4re")))]
169- use libc::{gid_t, uid_t};
168+ #[cfg(not(any(
169+ target_os = "vxworks",
170+ @@ -65,6 +65,10 @@ fn get_clock_resolution() -> Duration {
171+ }
172+ }
170173
171174+ use crate::ffi::OsString;
172175+ use crate::intrinsics::transmute;
@@ -175,8 +178,8 @@ index 3d305cd7310fd4b8419d220d1adeadebb9fda914..5d1c667b943cb2af0e0e918c17a7b242
175178 ////////////////////////////////////////////////////////////////////////////////
176179 // Command
177180 ////////////////////////////////////////////////////////////////////////////////
178- @@ -61 ,6 +65 ,65 @@ pub fn spawn(
179-
181+ @@ -93 ,6 +97 ,65 @@ pub fn spawn(
182+ }
180183 let (input, output) = sys::pipe::anon_pipe()?;
181184
182185+ // If there is a RUST_EXEC_SHIM (could be "/usr/bin/env --")
@@ -241,16 +244,16 @@ index 3d305cd7310fd4b8419d220d1adeadebb9fda914..5d1c667b943cb2af0e0e918c17a7b242
241244 // Whatever happens after the fork is almost for sure going to touch or
242245 // look at the environment in one way or another (PATH in `execvp` or
243246 // accessing the `environ` pointer ourselves). Make sure no other thread
244- @@ -76 ,7 +139 ,7 @@ pub fn spawn(
247+ @@ -109 ,7 +172 ,7 @@ pub fn spawn(
245248 if pid == 0 {
246249 crate::panic::always_abort();
247- mem::forget(env_lock);
250+ mem::forget(env_lock); // avoid non-async-signal-safe unlocking
248251- drop(input);
249252+ self.unwrap_drop(input);
250253 let Err(err) = unsafe { self.do_exec(theirs, envp.as_ref()) };
251254 let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;
252255 let errno = errno.to_be_bytes();
253- @@ -243 ,7 +306 ,48 @@ pub fn exec(&mut self, default: Stdio) -> io::Error {
256+ @@ -336 ,7 +399 ,48 @@ pub fn exec(&mut self, default: Stdio) -> io::Error {
254257 Err(e) => e,
255258 }
256259 }
@@ -300,7 +303,7 @@ index 3d305cd7310fd4b8419d220d1adeadebb9fda914..5d1c667b943cb2af0e0e918c17a7b242
300303 // And at this point we've reached a special time in the life of the
301304 // child. The child must now be considered hamstrung and unable to
302305 // do anything other than syscalls really. Consider the following
303- @@ -282 ,13 +386 ,13 @@ unsafe fn do_exec(
306+ @@ -376 ,13 +480 ,13 @@ unsafe fn do_exec(
304307 use crate::sys::{self, cvt_r};
305308
306309 if let Some(fd) = stdio.stdin.fd() {
@@ -317,7 +320,7 @@ index 3d305cd7310fd4b8419d220d1adeadebb9fda914..5d1c667b943cb2af0e0e918c17a7b242
317320 }
318321
319322 #[cfg(not(target_os = "l4re"))]
320- @@ -296 ,10 +400 ,10 @@ unsafe fn do_exec(
323+ @@ -390 ,10 +494 ,10 @@ unsafe fn do_exec(
321324 if let Some(_g) = self.get_groups() {
322325 //FIXME: Redox kernel does not support setgroups yet
323326 #[cfg(not(target_os = "redox"))]
@@ -330,12 +333,12 @@ index 3d305cd7310fd4b8419d220d1adeadebb9fda914..5d1c667b943cb2af0e0e918c17a7b242
330333 }
331334 if let Some(u) = self.get_uid() {
332335 // When dropping privileges from root, the `setgroups` call
333- @@ -311 ,13 +415 ,13 @@ unsafe fn do_exec(
336+ @@ -405 ,13 +509 ,13 @@ unsafe fn do_exec(
334337 //FIXME: Redox kernel does not support setgroups yet
335338 #[cfg(not(target_os = "redox"))]
336339 if libc::getuid() == 0 && self.get_groups().is_none() {
337- - cvt(libc::setgroups(0, ptr::null()))?;
338- + cvt(self.unwrap_setgroups(0, ptr::null()))?;
340+ - cvt(libc::setgroups(0, crate:: ptr::null()))?;
341+ + cvt(self.unwrap_setgroups(0, crate:: ptr::null()))?;
339342 }
340343- cvt(libc::setuid(u as uid_t))?;
341344+ cvt(self.unwrap_setuid(u as uid_t))?;
@@ -347,7 +350,7 @@ index 3d305cd7310fd4b8419d220d1adeadebb9fda914..5d1c667b943cb2af0e0e918c17a7b242
347350 }
348351
349352 if let Some(pgroup) = self.get_pgroup() {
350- @@ -378 ,8 +482 ,12 @@ fn drop(&mut self) {
353+ @@ -469 ,8 +573 ,12 @@ fn drop(&mut self) {
351354 _reset = Some(Reset(*sys::os::environ()));
352355 *sys::os::environ() = envp.as_ptr();
353356 }
@@ -362,17 +365,17 @@ index 3d305cd7310fd4b8419d220d1adeadebb9fda914..5d1c667b943cb2af0e0e918c17a7b242
362365 Err(io::Error::last_os_error())
363366 }
364367
365- @@ -394 ,6 +502 ,7 @@ fn posix_spawn(
368+ @@ -497 ,6 +605 ,7 @@ fn posix_spawn(
366369 _: &ChildPipes,
367370 _: Option<&CStringArray>,
368371 ) -> io::Result<Option<Process>> {
369372+ eprintln!("process_unix:270: in null posix_spawn");
370373 Ok(None)
371374 }
372375
373- @@ -413 ,12 +522 ,15 @@ fn posix_spawn(
376+ @@ -520 ,12 +629 ,15 @@ fn posix_spawn(
374377 use crate::mem::MaybeUninit;
375- use crate::sys::{self, cvt_nz};
378+ use crate::sys::{self, cvt_nz, unix_sigpipe_attr_specified };
376379
377380+ let skip_spawnvp: bool = getenv(&OsString::from("SB2_RUST_NO_SPAWNVP")).is_some();
378381+
@@ -386,3 +389,6 @@ index 3d305cd7310fd4b8419d220d1adeadebb9fda914..5d1c667b943cb2af0e0e918c17a7b242
386389 {
387390 return Ok(None);
388391 }
392+ - -
393+ 2.42.0
394+
0 commit comments