@@ -34,21 +34,25 @@ needed to support the SHIM functionality
34
34
35
35
Signed-off-by: David Greaves <david.greaves@jolla.com>
36
36
---
37
- src/libstd /sys/unix/process/process_common.rs | 40 ++++-
38
- src/libstd /sys/unix/process/process_unix.rs | 138 ++++++++++++++++--
37
+ library/std/src /sys/unix/process/process_common.rs | 40 ++++-
38
+ library/std/src /sys/unix/process/process_unix.rs | 138 ++++++++++++++++--
39
39
2 files changed, 160 insertions(+), 18 deletions(-)
40
40
41
- diff --git a/src/libstd/ sys/unix/process/process_common.rs b/src/libstd /sys/unix/process/process_common.rs
41
+ diff --git a/library/std/src/ sys/unix/process/process_common.rs b/library/std/src /sys/unix/process/process_common.rs
42
42
index 859da691ad2..ee5e776efac 100644
43
- --- a/src/libstd /sys/unix/process/process_common.rs
44
- +++ b/src/libstd /sys/unix/process/process_common.rs
45
- @@ -71,10 +71,16 @@ pub struct Command {
46
- // located. Whenever we add a key we update it in place if it's already
47
- // present, and whenever we remove a key we update the locations of all
48
- // other keys.
43
+ --- a/library/std/src /sys/unix/process/process_common.rs
44
+ +++ b/library/std/src /sys/unix/process/process_common.rs
45
+ @@ -60,7 +60,7 @@
46
+ ////////////////////////////////////////////////////////////////////////////////
47
+
48
+ pub struct Command {
49
49
- program: CString,
50
50
+ pub(crate) program: CString,
51
51
args: Vec<CString>,
52
+ /// Exactly what will be passed to `execvp`.
53
+ ///
54
+ @@ -69,6 +69,13 @@
55
+ /// `args` to properly update this as well.
52
56
argv: Argv,
53
57
env: CommandEnv,
54
58
+ pub(crate) execvp: Option<ExecvpFn>,
@@ -57,24 +61,26 @@ index 859da691ad2..ee5e776efac 100644
57
61
+ pub(crate) chdir: Option<ChdirFn>,
58
62
+ pub(crate) setuid: Option<SetuidFn>,
59
63
+ pub(crate) setgid: Option<SetgidFn>,
60
-
64
+ + pub(crate) setgroups: Option<SetgroupsFn>,
65
+
61
66
cwd: Option<CString>,
62
67
uid: Option<uid_t>,
63
- @@ -86 ,6 +92,13 @@ pub struct Command {
68
+ @@ -81 ,6 +88,14 @@
64
69
stderr: Option<Stdio>,
65
70
}
66
-
71
+
67
72
+ pub(crate) type ExecvpFn = fn(*const c_char, *const *const c_char)->c_int;
68
73
+ pub(crate) type Dup2Fn = fn(c_int, c_int)->c_int;
69
74
+ pub(crate) type CloseFn = fn(c_int)->c_int;
70
75
+ pub(crate) type ChdirFn = fn(*const c_char)->c_int;
71
76
+ pub(crate) type SetuidFn = fn(uid_t)->c_int;
72
77
+ pub(crate) type SetgidFn = fn(gid_t)->c_int;
73
- +
74
- // Create a new type for argv, so that we can make it `Send`
78
+ + pub(crate) type SetgroupsFn = fn(libc::size_t, *const gid_t)->c_int;
79
+ +
80
+ // Create a new type for argv, so that we can make it `Send` and `Sync`
75
81
struct Argv(Vec<*const c_char>);
76
-
77
- @@ -130,15 +143,22 @@ impl Command {
82
+
83
+ @@ -130,15 +143,23 @@ impl Command {
78
84
pub fn new(program: &OsStr) -> Command {
79
85
let mut saw_nul = false;
80
86
let program = os2c(program, &mut saw_nul);
@@ -93,6 +99,7 @@ index 859da691ad2..ee5e776efac 100644
93
99
+ chdir: None,
94
100
+ setuid: None,
95
101
+ setgid: None,
102
+ + setgroups: None,
96
103
cwd: None,
97
104
uid: None,
98
105
gid: None,
@@ -118,14 +125,14 @@ index 859da691ad2..ee5e776efac 100644
118
125
pub fn set_arg_0(&mut self, arg: &OsStr) {
119
126
// Set a new arg0
120
127
let arg = os2c(arg, &mut self.saw_nul);
121
- diff --git a/src/libstd/ sys/unix/process/process_unix.rs b/src/libstd /sys/unix/process/process_unix.rs
128
+ diff --git a/library/std/src/ sys/unix/process/process_unix.rs b/library/std/src /sys/unix/process/process_unix.rs
122
129
index f389c60615f..d5763b8aa1a 100644
123
- --- a/src/libstd/sys/unix/process/process_unix.rs
124
- +++ b/src/libstd/sys/unix/process/process_unix.rs
125
- @@ -5,7 +5,10 @@ use crate::sys;
126
- use crate::sys::cvt;
127
- use crate::sys::process::process_common::*;
130
+ --- a/library/std/src/sys/unix/process/process_unix.rs
131
+ +++ b/library/std/src/sys/unix/process/process_unix.rs
132
+ @@ -5,7 +5,10 @@ #[cfg(target_os = "vxworks")]
133
+ use libc::RTP_ID as pid_t;
128
134
135
+ #[cfg(not(target_os = "vxworks"))]
129
136
- use libc::{c_int, gid_t, pid_t, uid_t};
130
137
+ use libc::{c_int, gid_t, pid_t, uid_t, dlsym, c_char};
131
138
+ use crate::intrinsics::transmute;
@@ -134,7 +141,7 @@ index f389c60615f..d5763b8aa1a 100644
134
141
135
142
////////////////////////////////////////////////////////////////////////////////
136
143
// Command
137
- @@ -33 ,6 +36,70 @@ impl Command {
144
+ @@ -35 ,6 +41,74 @@ impl Command {
138
145
139
146
let (input, output) = sys::pipe::anon_pipe()?;
140
147
@@ -196,6 +203,10 @@ index f389c60615f..d5763b8aa1a 100644
196
203
+ "setgid\0".as_ptr() as *const c_char) as *const ();
197
204
+ self.setgid = Some(
198
205
+ transmute::<*const (), SetgidFn>(real_setgid_p) );
206
+ + let real_setgroups_p = dlsym(libc_h,
207
+ + "setgroups\0".as_ptr() as *const c_char) as *const ();
208
+ + self.setgroups = Some(
209
+ + transmute::<*const (), SetgroupsFn>(real_setgroups_p) );
199
210
+ },
200
211
+ None => {}
201
212
+ };
@@ -205,21 +216,16 @@ index f389c60615f..d5763b8aa1a 100644
205
216
// Whatever happens after the fork is almost for sure going to touch or
206
217
// look at the environment in one way or another (PATH in `execvp` or
207
218
// accessing the `environ` pointer ourselves). Make sure no other thread
208
- @@ -45,11 +112,11 @@ impl Command {
209
- let _env_lock = sys::os::env_lock();
210
- cvt(libc::fork())?
211
- };
212
- -
213
- +
214
- let pid = unsafe {
219
+ @@ -54,7 +125,7 @@
215
220
match result {
216
221
0 => {
222
+ mem::forget(env_lock);
217
223
- drop(input);
218
224
+ self.unwrap_drop(input);
219
225
let Err(err) = self.do_exec(theirs, envp.as_ref());
220
226
let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;
221
- let bytes = [
222
- @@ -135,7 +202,37 @@ impl Command {
227
+ let errno = errno.to_be_bytes();
228
+ @@ -135,7 +202,43 @@ impl Command {
223
229
Err(e) => e,
224
230
}
225
231
}
@@ -254,11 +260,17 @@ index f389c60615f..d5763b8aa1a 100644
254
260
+ Some(real_setgid) => { (real_setgid)(gid) },
255
261
+ None => { unsafe { libc::setgid(gid) } }
256
262
+ }
263
+ + }
264
+ + fn unwrap_setgroups(&self, ngroups: libc::size_t, gid: *const gid_t) -> c_int {
265
+ + match self.setgroups {
266
+ + Some(real_setgroups) => { (real_setgroups)(ngroups, gid) },
267
+ + None => { unsafe { libc::setgroups(ngroups, gid) } }
268
+ + }
257
269
+ }
258
270
// And at this point we've reached a special time in the life of the
259
271
// child. The child must now be considered hamstrung and unable to
260
272
// do anything other than syscalls really. Consider the following
261
- @@ -174,19 +271,19 @@ impl Command {
273
+ @@ -174,24 +277,24 @@ impl Command {
262
274
use crate::sys::{self, cvt_r};
263
275
264
276
if let Some(fd) = stdio.stdin.fd() {
@@ -276,16 +288,25 @@ index f389c60615f..d5763b8aa1a 100644
276
288
277
289
#[cfg(not(target_os = "l4re"))]
278
290
{
291
+ if let Some(_g) = self.get_groups() {
292
+ //FIXME: Redox kernel does not support setgroups yet
293
+ #[cfg(not(target_os = "redox"))]
294
+ - cvt(libc::setgroups(_g.len().try_into().unwrap(), _g.as_ptr()))?;
295
+ + cvt(self.unwrap_setgroups(_g.len().try_into().unwrap(), _g.as_ptr()))?;
296
+ }
279
297
if let Some(u) = self.get_gid() {
280
298
- cvt(libc::setgid(u as gid_t))?;
281
299
+ cvt(self.unwrap_setgid(u as gid_t))?;
282
300
}
283
301
if let Some(u) = self.get_uid() {
284
302
// When dropping privileges from root, the `setgroups` call
285
- @@ -199,11 +296,11 @@ impl Command {
303
+ @@ -199,13 +296,13 @@ impl Command {
286
304
//FIXME: Redox kernel does not support setgroups yet
287
305
#[cfg(not(target_os = "redox"))]
288
- let _ = libc::setgroups(0, ptr::null());
306
+ if libc::getuid() == 0 && self.get_groups().is_none() {
307
+ - cvt(libc::setgroups(0, ptr::null()))?;
308
+ + cvt(self.unwrap_setgroups(0, ptr::null()))?;
309
+ }
289
310
- cvt(libc::setuid(u as uid_t))?;
290
311
+ cvt(self.unwrap_setuid(u as uid_t))?;
291
312
}
@@ -301,15 +322,15 @@ index f389c60615f..d5763b8aa1a 100644
301
322
*sys::os::environ() = envp.as_ptr();
302
323
}
303
324
-
304
- - libc::execvp(self.get_program ().as_ptr(), self.get_argv().as_ptr());
325
+ - libc::execvp(self.get_program_cstr ().as_ptr(), self.get_argv().as_ptr());
305
326
- Err(io::Error::last_os_error())
306
327
+ match self.execvp {
307
328
+ Some(real_execvp) => {
308
- + (real_execvp)(self.get_program ().as_ptr(),
329
+ + (real_execvp)(self.get_program_cstr ().as_ptr(),
309
330
+ self.get_argv().as_ptr())
310
331
+ },
311
332
+ None => {
312
- + libc::execvp(self.get_program ().as_ptr(),
333
+ + libc::execvp(self.get_program_cstr ().as_ptr(),
313
334
+ self.get_argv().as_ptr())
314
335
+ }
315
336
+ };
@@ -325,23 +346,20 @@ index f389c60615f..d5763b8aa1a 100644
325
346
Ok(None)
326
347
}
327
348
328
- @@ -283,10 +389,16 @@ impl Command {
349
+ @@ -283,11 +389,14 @@ impl Command {
329
350
use crate::mem::MaybeUninit;
330
- use crate::sys;
351
+ use crate::sys::{self, cvt_nz} ;
331
352
332
- + let skip_spawnvp :bool = match getenv(&OsString::from("SB2_RUST_NO_SPAWNVP"))? {
333
- + Some(_var) => true,
334
- + None => false
335
- + };
353
+ + let skip_spawnvp: bool = getenv(&OsString::from("SB2_RUST_NO_SPAWNVP"))?.is_some();
336
354
+
337
355
if self.get_gid().is_some()
338
356
|| self.get_uid().is_some()
339
- || self.env_saw_path()
357
+ || ( self.env_saw_path() && !self.program_is_path() )
340
358
|| !self.get_closures().is_empty()
359
+ || self.get_groups().is_some()
341
360
+ || skip_spawnvp
342
361
{
343
362
return Ok(None);
344
363
}
345
364
- -
346
365
2.20.1
347
-
0 commit comments