Skip to content

Commit 4fa0418

Browse files
committed
Move the mount tests into the "test" program
Now that we aren't using namespaces, they don't need their own program.
1 parent 60f2290 commit 4fa0418

File tree

3 files changed

+158
-164
lines changed

3 files changed

+158
-164
lines changed

Cargo.toml

-4
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,6 @@ path = "test/sys/test_aio_drop.rs"
9999
name = "test-clearenv"
100100
path = "test/test_clearenv.rs"
101101

102-
[[test]]
103-
name = "test-mount"
104-
path = "test/test_mount.rs"
105-
106102
[[test]]
107103
name = "test-prctl"
108104
path = "test/sys/test_prctl.rs"

test/test.rs

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ mod test_errno;
1111
mod test_fcntl;
1212
#[cfg(linux_android)]
1313
mod test_kmod;
14+
#[cfg(target_os = "linux")]
15+
mod test_mount;
1416
#[cfg(any(
1517
freebsdlike,
1618
target_os = "fushsia",

test/test_mount.rs

+156-160
Original file line numberDiff line numberDiff line change
@@ -1,187 +1,183 @@
1-
#[macro_use]
2-
mod common;
1+
use std::fs::{self, File};
2+
use std::io::{Read, Write};
3+
use std::os::unix::fs::OpenOptionsExt;
4+
use std::os::unix::fs::PermissionsExt;
5+
use std::process::Command;
36

4-
#[cfg(target_os = "linux")]
5-
mod test_mount {
6-
use std::fs::{self, File};
7-
use std::io::{Read, Write};
8-
use std::os::unix::fs::OpenOptionsExt;
9-
use std::os::unix::fs::PermissionsExt;
10-
use std::process::Command;
7+
use libc::{EACCES, EROFS};
118

12-
use libc::{EACCES, EROFS};
9+
use nix::mount::{mount, umount, MsFlags};
10+
use nix::sys::stat::{self, Mode};
1311

14-
use nix::mount::{mount, umount, MsFlags};
15-
use nix::sys::stat::{self, Mode};
12+
use crate::*;
1613

17-
static SCRIPT_CONTENTS: &[u8] = b"#!/bin/sh
14+
static SCRIPT_CONTENTS: &[u8] = b"#!/bin/sh
1815
exit 23";
1916

20-
const EXPECTED_STATUS: i32 = 23;
21-
22-
const NONE: Option<&'static [u8]> = None;
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-
);
30-
let tempdir = tempfile::tempdir().unwrap();
31-
32-
mount(
33-
NONE,
34-
tempdir.path(),
35-
Some(b"tmpfs".as_ref()),
36-
MsFlags::empty(),
37-
NONE,
38-
)
39-
.unwrap_or_else(|e| panic!("mount failed: {e}"));
40-
41-
let test_path = tempdir.path().join("test");
42-
43-
// Verify write.
44-
fs::OpenOptions::new()
45-
.create(true)
46-
.write(true)
47-
.mode((Mode::S_IRWXU | Mode::S_IRWXG | Mode::S_IRWXO).bits())
48-
.open(&test_path)
49-
.and_then(|mut f| f.write(SCRIPT_CONTENTS))
50-
.unwrap_or_else(|e| panic!("write failed: {e}"));
51-
52-
// Verify read.
53-
let mut buf = Vec::new();
54-
File::open(&test_path)
55-
.and_then(|mut f| f.read_to_end(&mut buf))
56-
.unwrap_or_else(|e| panic!("read failed: {e}"));
57-
assert_eq!(buf, SCRIPT_CONTENTS);
58-
59-
// Verify execute.
60-
assert_eq!(
61-
EXPECTED_STATUS,
62-
Command::new(&test_path)
63-
.status()
64-
.unwrap_or_else(|e| panic!("exec failed: {e}"))
65-
.code()
66-
.unwrap_or_else(|| panic!("child killed by signal"))
67-
);
68-
69-
umount(tempdir.path()).unwrap_or_else(|e| panic!("umount failed: {e}"));
70-
}
71-
72-
#[test]
73-
fn test_mount_rdonly_disallows_write() {
74-
require_capability!("test_mount_rdonly_disallows_write", CAP_SYS_ADMIN);
75-
let tempdir = tempfile::tempdir().unwrap();
17+
const EXPECTED_STATUS: i32 = 23;
18+
19+
const NONE: Option<&'static [u8]> = None;
20+
21+
#[test]
22+
fn test_mount_tmpfs_without_flags_allows_rwx() {
23+
require_capability!(
24+
"test_mount_tmpfs_without_flags_allows_rwx",
25+
CAP_SYS_ADMIN
26+
);
27+
let tempdir = tempfile::tempdir().unwrap();
28+
29+
mount(
30+
NONE,
31+
tempdir.path(),
32+
Some(b"tmpfs".as_ref()),
33+
MsFlags::empty(),
34+
NONE,
35+
)
36+
.unwrap_or_else(|e| panic!("mount failed: {e}"));
37+
38+
let test_path = tempdir.path().join("test");
39+
40+
// Verify write.
41+
fs::OpenOptions::new()
42+
.create(true)
43+
.write(true)
44+
.mode((Mode::S_IRWXU | Mode::S_IRWXG | Mode::S_IRWXO).bits())
45+
.open(&test_path)
46+
.and_then(|mut f| f.write(SCRIPT_CONTENTS))
47+
.unwrap_or_else(|e| panic!("write failed: {e}"));
48+
49+
// Verify read.
50+
let mut buf = Vec::new();
51+
File::open(&test_path)
52+
.and_then(|mut f| f.read_to_end(&mut buf))
53+
.unwrap_or_else(|e| panic!("read failed: {e}"));
54+
assert_eq!(buf, SCRIPT_CONTENTS);
55+
56+
// Verify execute.
57+
assert_eq!(
58+
EXPECTED_STATUS,
59+
Command::new(&test_path)
60+
.status()
61+
.unwrap_or_else(|e| panic!("exec failed: {e}"))
62+
.code()
63+
.unwrap_or_else(|| panic!("child killed by signal"))
64+
);
65+
66+
umount(tempdir.path()).unwrap_or_else(|e| panic!("umount failed: {e}"));
67+
}
7668

77-
mount(
78-
NONE,
79-
tempdir.path(),
80-
Some(b"tmpfs".as_ref()),
81-
MsFlags::MS_RDONLY,
82-
NONE,
83-
)
84-
.unwrap_or_else(|e| panic!("mount failed: {e}"));
69+
#[test]
70+
fn test_mount_rdonly_disallows_write() {
71+
require_capability!("test_mount_rdonly_disallows_write", CAP_SYS_ADMIN);
72+
let tempdir = tempfile::tempdir().unwrap();
73+
74+
mount(
75+
NONE,
76+
tempdir.path(),
77+
Some(b"tmpfs".as_ref()),
78+
MsFlags::MS_RDONLY,
79+
NONE,
80+
)
81+
.unwrap_or_else(|e| panic!("mount failed: {e}"));
82+
83+
// EROFS: Read-only file system
84+
assert_eq!(
85+
EROFS,
86+
File::create(tempdir.path().join("test"))
87+
.unwrap_err()
88+
.raw_os_error()
89+
.unwrap()
90+
);
91+
92+
umount(tempdir.path()).unwrap_or_else(|e| panic!("umount failed: {e}"));
93+
}
8594

86-
// EROFS: Read-only file system
87-
assert_eq!(
88-
EROFS,
89-
File::create(tempdir.path().join("test"))
90-
.unwrap_err()
91-
.raw_os_error()
92-
.unwrap()
93-
);
95+
#[test]
96+
fn test_mount_noexec_disallows_exec() {
97+
require_capability!("test_mount_noexec_disallows_exec", CAP_SYS_ADMIN);
98+
let tempdir = tempfile::tempdir().unwrap();
99+
100+
mount(
101+
NONE,
102+
tempdir.path(),
103+
Some(b"tmpfs".as_ref()),
104+
MsFlags::MS_NOEXEC,
105+
NONE,
106+
)
107+
.unwrap_or_else(|e| panic!("mount failed: {e}"));
108+
109+
let test_path = tempdir.path().join("test");
110+
111+
fs::OpenOptions::new()
112+
.create(true)
113+
.write(true)
114+
.mode((Mode::S_IRWXU | Mode::S_IRWXG | Mode::S_IRWXO).bits())
115+
.open(&test_path)
116+
.and_then(|mut f| f.write(SCRIPT_CONTENTS))
117+
.unwrap_or_else(|e| panic!("write failed: {e}"));
118+
119+
// Verify that we cannot execute despite a+x permissions being set.
120+
let mode = stat::Mode::from_bits_truncate(
121+
fs::metadata(&test_path)
122+
.map(|md| md.permissions().mode())
123+
.unwrap_or_else(|e| panic!("metadata failed: {e}")),
124+
);
125+
126+
assert!(
127+
mode.contains(Mode::S_IXUSR | Mode::S_IXGRP | Mode::S_IXOTH),
128+
"{:?} did not have execute permissions",
129+
&test_path
130+
);
131+
132+
// EACCES: Permission denied
133+
assert_eq!(
134+
EACCES,
135+
Command::new(&test_path)
136+
.status()
137+
.unwrap_err()
138+
.raw_os_error()
139+
.unwrap()
140+
);
141+
142+
umount(tempdir.path()).unwrap_or_else(|e| panic!("umount failed: {e}"));
143+
}
94144

95-
umount(tempdir.path()).unwrap_or_else(|e| panic!("umount failed: {e}"));
96-
}
145+
#[test]
146+
fn test_mount_bind() {
147+
require_capability!("test_mount_bind", CAP_SYS_ADMIN);
148+
let tempdir = tempfile::tempdir().unwrap();
149+
let file_name = "test";
97150

98-
#[test]
99-
fn test_mount_noexec_disallows_exec() {
100-
require_capability!("test_mount_noexec_disallows_exec", CAP_SYS_ADMIN);
101-
let tempdir = tempfile::tempdir().unwrap();
151+
{
152+
let mount_point = tempfile::tempdir().unwrap();
102153

103154
mount(
155+
Some(tempdir.path()),
156+
mount_point.path(),
104157
NONE,
105-
tempdir.path(),
106-
Some(b"tmpfs".as_ref()),
107-
MsFlags::MS_NOEXEC,
158+
MsFlags::MS_BIND,
108159
NONE,
109160
)
110161
.unwrap_or_else(|e| panic!("mount failed: {e}"));
111162

112-
let test_path = tempdir.path().join("test");
113-
114163
fs::OpenOptions::new()
115164
.create(true)
116165
.write(true)
117166
.mode((Mode::S_IRWXU | Mode::S_IRWXG | Mode::S_IRWXO).bits())
118-
.open(&test_path)
167+
.open(mount_point.path().join(file_name))
119168
.and_then(|mut f| f.write(SCRIPT_CONTENTS))
120169
.unwrap_or_else(|e| panic!("write failed: {e}"));
121170

122-
// Verify that we cannot execute despite a+x permissions being set.
123-
let mode = stat::Mode::from_bits_truncate(
124-
fs::metadata(&test_path)
125-
.map(|md| md.permissions().mode())
126-
.unwrap_or_else(|e| panic!("metadata failed: {e}")),
127-
);
128-
129-
assert!(
130-
mode.contains(Mode::S_IXUSR | Mode::S_IXGRP | Mode::S_IXOTH),
131-
"{:?} did not have execute permissions",
132-
&test_path
133-
);
134-
135-
// EACCES: Permission denied
136-
assert_eq!(
137-
EACCES,
138-
Command::new(&test_path)
139-
.status()
140-
.unwrap_err()
141-
.raw_os_error()
142-
.unwrap()
143-
);
144-
145-
umount(tempdir.path()).unwrap_or_else(|e| panic!("umount failed: {e}"));
171+
umount(mount_point.path())
172+
.unwrap_or_else(|e| panic!("umount failed: {e}"));
146173
}
147174

148-
#[test]
149-
fn test_mount_bind() {
150-
require_capability!("test_mount_bind", CAP_SYS_ADMIN);
151-
let tempdir = tempfile::tempdir().unwrap();
152-
let file_name = "test";
153-
154-
{
155-
let mount_point = tempfile::tempdir().unwrap();
156-
157-
mount(
158-
Some(tempdir.path()),
159-
mount_point.path(),
160-
NONE,
161-
MsFlags::MS_BIND,
162-
NONE,
163-
)
164-
.unwrap_or_else(|e| panic!("mount failed: {e}"));
165-
166-
fs::OpenOptions::new()
167-
.create(true)
168-
.write(true)
169-
.mode((Mode::S_IRWXU | Mode::S_IRWXG | Mode::S_IRWXO).bits())
170-
.open(mount_point.path().join(file_name))
171-
.and_then(|mut f| f.write(SCRIPT_CONTENTS))
172-
.unwrap_or_else(|e| panic!("write failed: {e}"));
173-
174-
umount(mount_point.path())
175-
.unwrap_or_else(|e| panic!("umount failed: {e}"));
176-
}
177-
178-
// Verify the file written in the mount shows up in source directory, even
179-
// after unmounting.
180-
181-
let mut buf = Vec::new();
182-
File::open(tempdir.path().join(file_name))
183-
.and_then(|mut f| f.read_to_end(&mut buf))
184-
.unwrap_or_else(|e| panic!("read failed: {e}"));
185-
assert_eq!(buf, SCRIPT_CONTENTS);
186-
}
175+
// Verify the file written in the mount shows up in source directory, even
176+
// after unmounting.
177+
178+
let mut buf = Vec::new();
179+
File::open(tempdir.path().join(file_name))
180+
.and_then(|mut f| f.read_to_end(&mut buf))
181+
.unwrap_or_else(|e| panic!("read failed: {e}"));
182+
assert_eq!(buf, SCRIPT_CONTENTS);
187183
}

0 commit comments

Comments
 (0)