1
+ #[ macro_use]
1
2
mod common;
2
3
3
- // Implementation note: to allow unprivileged users to run it, this test makes
4
- // use of user and mount namespaces. On systems that allow unprivileged user
5
- // namespaces (Linux >= 3.8 compiled with CONFIG_USER_NS), the test should run
6
- // without root.
7
-
8
4
#[ cfg( target_os = "linux" ) ]
9
5
mod test_mount {
10
6
use std:: fs:: { self , File } ;
11
- use std:: io:: { self , Read , Write } ;
7
+ use std:: io:: { Read , Write } ;
12
8
use std:: os:: unix:: fs:: OpenOptionsExt ;
13
9
use std:: os:: unix:: fs:: PermissionsExt ;
14
- use std:: process:: { self , Command } ;
10
+ use std:: process:: Command ;
15
11
16
12
use libc:: { EACCES , EROFS } ;
17
13
18
- use nix:: errno:: Errno ;
19
14
use nix:: mount:: { mount, umount, MsFlags } ;
20
- use nix:: sched:: { unshare, CloneFlags } ;
21
15
use nix:: sys:: stat:: { self , Mode } ;
22
- use nix:: unistd:: getuid;
23
16
24
17
static SCRIPT_CONTENTS : & [ u8 ] = b"#!/bin/sh
25
18
exit 23" ;
26
19
27
20
const EXPECTED_STATUS : i32 = 23 ;
28
21
29
22
const NONE : Option < & ' static [ u8 ] > = None ;
30
- #[ allow( clippy:: bind_instead_of_map) ] // False positive
31
- pub fn test_mount_tmpfs_without_flags_allows_rwx ( ) {
23
+
24
+ #[ test]
25
+ fn test_mount_tmpfs_without_flags_allows_rwx ( ) {
26
+ require_capability ! (
27
+ "test_mount_tmpfs_without_flags_allows_rwx" ,
28
+ CAP_SYS_ADMIN
29
+ ) ;
32
30
let tempdir = tempfile:: tempdir ( ) . unwrap ( ) ;
33
31
34
32
mount (
@@ -48,28 +46,6 @@ exit 23";
48
46
. write ( true )
49
47
. mode ( ( Mode :: S_IRWXU | Mode :: S_IRWXG | Mode :: S_IRWXO ) . bits ( ) )
50
48
. open ( & test_path)
51
- . or_else ( |e| {
52
- if Errno :: from_raw ( e. raw_os_error ( ) . unwrap ( ) )
53
- == Errno :: EOVERFLOW
54
- {
55
- // Skip tests on certain Linux kernels which have a bug
56
- // regarding tmpfs in namespaces.
57
- // Ubuntu 14.04 and 16.04 are known to be affected; 16.10 is
58
- // not. There is no legitimate reason for open(2) to return
59
- // EOVERFLOW here.
60
- // https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1659087
61
- let stderr = io:: stderr ( ) ;
62
- let mut handle = stderr. lock ( ) ;
63
- writeln ! (
64
- handle,
65
- "Buggy Linux kernel detected. Skipping test."
66
- )
67
- . unwrap ( ) ;
68
- process:: exit ( 0 ) ;
69
- } else {
70
- panic ! ( "open failed: {e}" ) ;
71
- }
72
- } )
73
49
. and_then ( |mut f| f. write ( SCRIPT_CONTENTS ) )
74
50
. unwrap_or_else ( |e| panic ! ( "write failed: {e}" ) ) ;
75
51
@@ -93,7 +69,9 @@ exit 23";
93
69
umount ( tempdir. path ( ) ) . unwrap_or_else ( |e| panic ! ( "umount failed: {e}" ) ) ;
94
70
}
95
71
96
- pub fn test_mount_rdonly_disallows_write ( ) {
72
+ #[ test]
73
+ fn test_mount_rdonly_disallows_write ( ) {
74
+ require_capability ! ( "test_mount_rdonly_disallows_write" , CAP_SYS_ADMIN ) ;
97
75
let tempdir = tempfile:: tempdir ( ) . unwrap ( ) ;
98
76
99
77
mount (
@@ -117,7 +95,9 @@ exit 23";
117
95
umount ( tempdir. path ( ) ) . unwrap_or_else ( |e| panic ! ( "umount failed: {e}" ) ) ;
118
96
}
119
97
120
- pub fn test_mount_noexec_disallows_exec ( ) {
98
+ #[ test]
99
+ fn test_mount_noexec_disallows_exec ( ) {
100
+ require_capability ! ( "test_mount_noexec_disallows_exec" , CAP_SYS_ADMIN ) ;
121
101
let tempdir = tempfile:: tempdir ( ) . unwrap ( ) ;
122
102
123
103
mount (
@@ -165,7 +145,9 @@ exit 23";
165
145
umount ( tempdir. path ( ) ) . unwrap_or_else ( |e| panic ! ( "umount failed: {e}" ) ) ;
166
146
}
167
147
168
- pub fn test_mount_bind ( ) {
148
+ #[ test]
149
+ fn test_mount_bind ( ) {
150
+ require_capability ! ( "test_mount_bind" , CAP_SYS_ADMIN ) ;
169
151
let tempdir = tempfile:: tempdir ( ) . unwrap ( ) ;
170
152
let file_name = "test" ;
171
153
@@ -202,66 +184,4 @@ exit 23";
202
184
. unwrap_or_else ( |e| panic ! ( "read failed: {e}" ) ) ;
203
185
assert_eq ! ( buf, SCRIPT_CONTENTS ) ;
204
186
}
205
-
206
- pub fn setup_namespaces ( ) {
207
- // Hold on to the uid in the parent namespace.
208
- let uid = getuid ( ) ;
209
-
210
- unshare ( CloneFlags :: CLONE_NEWNS | CloneFlags :: CLONE_NEWUSER ) . unwrap_or_else ( |e| {
211
- let stderr = io:: stderr ( ) ;
212
- let mut handle = stderr. lock ( ) ;
213
- writeln ! ( handle,
214
- "unshare failed: {e}. Are unprivileged user namespaces available?" ) . unwrap ( ) ;
215
- writeln ! ( handle, "mount is not being tested" ) . unwrap ( ) ;
216
- // Exit with success because not all systems support unprivileged user namespaces, and
217
- // that's not what we're testing for.
218
- process:: exit ( 0 ) ;
219
- } ) ;
220
-
221
- // Map user as uid 1000.
222
- fs:: OpenOptions :: new ( )
223
- . write ( true )
224
- . open ( "/proc/self/uid_map" )
225
- . and_then ( |mut f| f. write ( format ! ( "1000 {uid} 1\n " ) . as_bytes ( ) ) )
226
- . unwrap_or_else ( |e| panic ! ( "could not write uid map: {e}" ) ) ;
227
- }
228
187
}
229
-
230
- // Test runner
231
-
232
- /// Mimic normal test output (hackishly).
233
- #[ cfg( target_os = "linux" ) ]
234
- macro_rules! run_tests {
235
- ( $( $test_fn: ident) ,* ) => { {
236
- println!( ) ;
237
-
238
- $(
239
- print!( "test test_mount::{} ... " , stringify!( $test_fn) ) ;
240
- $test_fn( ) ;
241
- println!( "ok" ) ;
242
- ) *
243
-
244
- println!( ) ;
245
- } }
246
- }
247
-
248
- #[ cfg( target_os = "linux" ) ]
249
- fn main ( ) {
250
- use test_mount:: {
251
- setup_namespaces, test_mount_bind, test_mount_noexec_disallows_exec,
252
- test_mount_rdonly_disallows_write,
253
- test_mount_tmpfs_without_flags_allows_rwx,
254
- } ;
255
- skip_if_cirrus ! ( "Fails for an unknown reason Cirrus CI. Bug #1351" ) ;
256
- setup_namespaces ( ) ;
257
-
258
- run_tests ! (
259
- test_mount_tmpfs_without_flags_allows_rwx,
260
- test_mount_rdonly_disallows_write,
261
- test_mount_noexec_disallows_exec,
262
- test_mount_bind
263
- ) ;
264
- }
265
-
266
- #[ cfg( not( target_os = "linux" ) ) ]
267
- fn main ( ) { }
0 commit comments