Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/jail/tests/fork.rs
5394 views
1
// Copyright 2022 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
#[cfg(any(target_os = "android", target_os = "linux"))]
6
mod test {
7
use std::thread;
8
use std::time::Duration;
9
10
use base::getpid;
11
use base::AsRawDescriptor;
12
use base::Tube;
13
use jail::fork::fork_process;
14
use minijail::Minijail;
15
16
pub fn pid_diff() {
17
let (tube, fork_tube) = Tube::pair().expect("failed to create tube");
18
let jail = Minijail::new().unwrap();
19
let keep_rds = vec![fork_tube.as_raw_descriptor()];
20
21
let pid = getpid();
22
let child = fork_process(jail, keep_rds, None, || {
23
// checks that this is a genuine fork with a new PID
24
if pid != getpid() {
25
fork_tube.send(&1).unwrap()
26
} else {
27
fork_tube.send(&2).unwrap()
28
}
29
})
30
.expect("failed to fork");
31
32
assert_eq!(tube.recv::<u32>().unwrap(), 1);
33
child.wait().unwrap();
34
}
35
36
pub fn thread_name() {
37
let (tube, fork_tube) = Tube::pair().expect("failed to create tube");
38
let jail = Minijail::new().unwrap();
39
let keep_rds = vec![fork_tube.as_raw_descriptor()];
40
let thread_name = String::from("thread_name");
41
42
let child = fork_process(jail, keep_rds, Some(thread_name.clone()), || {
43
fork_tube.send::<u32>(&1).unwrap();
44
thread::sleep(Duration::from_secs(10));
45
})
46
.expect("failed to fork");
47
48
// wait the forked process running.
49
tube.recv::<u32>().unwrap();
50
let thread_comm =
51
std::fs::read_to_string(format!("/proc/{0}/task/{0}/comm", child.pid)).unwrap();
52
53
assert_eq!(thread_comm, thread_name + "\n");
54
55
// SAFETY: child pid is expected to be valid and we wait on the child
56
unsafe { libc::kill(child.pid, libc::SIGKILL) };
57
child.wait().unwrap();
58
}
59
60
pub fn thread_name_trimmed() {
61
let (tube, fork_tube) = Tube::pair().expect("failed to create tube");
62
let jail = Minijail::new().unwrap();
63
let keep_rds = vec![fork_tube.as_raw_descriptor()];
64
let thread_name = String::from("12345678901234567890");
65
66
let child = fork_process(jail, keep_rds, Some(thread_name), || {
67
fork_tube.send::<u32>(&1).unwrap();
68
thread::sleep(Duration::from_secs(10));
69
})
70
.expect("failed to fork");
71
72
// wait the forked process running.
73
tube.recv::<u32>().unwrap();
74
let thread_comm =
75
std::fs::read_to_string(format!("/proc/{0}/task/{0}/comm", child.pid)).unwrap();
76
77
assert_eq!(thread_comm, "123456789012345\n");
78
79
// SAFETY: child pid is expected to be valid and we wait on the child
80
unsafe { libc::kill(child.pid, libc::SIGKILL) };
81
child.wait().unwrap();
82
}
83
84
pub fn wait_for_success() {
85
let jail = Minijail::new().unwrap();
86
let child = fork_process(jail, vec![], None, || {
87
// exit successfully
88
})
89
.expect("failed to fork");
90
91
assert_eq!(child.wait().unwrap(), 0);
92
}
93
94
pub fn wait_for_panic() {
95
let jail = Minijail::new().unwrap();
96
let child = fork_process(jail, vec![], None, || {
97
panic!("fails");
98
})
99
.expect("failed to fork");
100
101
assert_eq!(child.wait().unwrap(), 101);
102
}
103
}
104
105
fn main() {
106
let args = libtest_mimic::Arguments {
107
// Force single-threaded execution to allow safe use of libc::fork in these tests.
108
test_threads: Some(1),
109
..libtest_mimic::Arguments::from_args()
110
};
111
112
let tests = vec![
113
#[cfg(any(target_os = "android", target_os = "linux"))]
114
libtest_mimic::Trial::test("pid_diff", move || {
115
test::pid_diff();
116
Ok(())
117
}),
118
#[cfg(any(target_os = "android", target_os = "linux"))]
119
libtest_mimic::Trial::test("thread_name", move || {
120
test::thread_name();
121
Ok(())
122
}),
123
#[cfg(any(target_os = "android", target_os = "linux"))]
124
libtest_mimic::Trial::test("thread_name_trimmed", move || {
125
test::thread_name_trimmed();
126
Ok(())
127
}),
128
#[cfg(any(target_os = "android", target_os = "linux"))]
129
libtest_mimic::Trial::test("wait_for_success", move || {
130
test::wait_for_success();
131
Ok(())
132
}),
133
#[cfg(any(target_os = "android", target_os = "linux"))]
134
libtest_mimic::Trial::test("wait_for_panic", move || {
135
test::wait_for_panic();
136
Ok(())
137
}),
138
];
139
libtest_mimic::run(&args, tests).exit();
140
}
141
142