Skip to content

Commit a9b97db

Browse files
committed
cap-tempfile: Don't create anonymous files with 0o666
When creating anonymous temporary files, use mode 0o000 instead of 0o666 to further discourage anything else from opening them. This fixes a bug pointed out in #390.
1 parent ecc886d commit a9b97db

File tree

1 file changed

+33
-4
lines changed

1 file changed

+33
-4
lines changed

cap-tempfile/src/tempfile.rs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,17 @@ fn new_tempfile_linux(d: &Dir, anonymous: bool) -> io::Result<Option<File>> {
6868
if anonymous {
6969
oflags |= OFlags::EXCL;
7070
}
71-
// We default to 0o666, same as main rust when creating new files; this will be
72-
// modified by umask: <https://github.com/rust-lang/rust/blob/44628f7273052d0bb8e8218518dacab210e1fe0d/library/std/src/sys/unix/fs.rs#L762>
73-
let mode = Mode::from_raw_mode(0o666);
71+
// For anonymous files, open with no permissions to discourage other
72+
// processes from opening them.
73+
//
74+
// For named files, default to 0o666, same as main rust when creating new
75+
// files; this will be modified by umask:
76+
// <https://github.com/rust-lang/rust/blob/44628f7273052d0bb8e8218518dacab210e1fe0d/library/std/src/sys/unix/fs.rs#L762>
77+
let mode = if anonymous {
78+
Mode::from_raw_mode(0o000)
79+
} else {
80+
Mode::from_raw_mode(0o666)
81+
};
7482
// Happy path - Linux with O_TMPFILE
7583
match rustix::fs::openat(d, ".", oflags, mode) {
7684
Ok(r) => Ok(Some(File::from(r))),
@@ -111,6 +119,16 @@ fn new_tempfile(d: &Dir, anonymous: bool) -> io::Result<(File, Option<String>)>
111119
opts.read(true);
112120
opts.write(true);
113121
opts.create_new(true);
122+
#[cfg(unix)]
123+
if anonymous {
124+
use cap_std::fs::OpenOptionsExt;
125+
opts.mode(0);
126+
}
127+
#[cfg(windows)]
128+
if anonymous {
129+
use cap_std::fs::OpenOptionsExt;
130+
opts.share_mode(0);
131+
}
114132
let (f, name) = super::retry_with_name_ignoring(io::ErrorKind::AlreadyExists, |name| {
115133
d.open_with(name, &opts)
116134
})?;
@@ -262,7 +280,7 @@ mod test {
262280

263281
let mut tf = TempFile::new(&td)?;
264282
// Test that we created with the right permissions
265-
#[cfg(any(target_os = "android", target_os = "linux"))]
283+
#[cfg(unix)]
266284
{
267285
use cap_std::fs_utf8::MetadataExt;
268286
use rustix::fs::Mode;
@@ -291,6 +309,17 @@ mod test {
291309
let mut buf = String::new();
292310
tf.read_to_string(&mut buf).unwrap();
293311
assert_eq!(&buf, "hello world, I'm anonymous");
312+
313+
// Test that we created with the right permissions
314+
#[cfg(unix)]
315+
{
316+
use cap_std::fs_utf8::MetadataExt;
317+
use rustix::fs::Mode;
318+
let metadata = tf.metadata().unwrap();
319+
let mode = metadata.mode();
320+
let mode = Mode::from_bits_truncate(mode);
321+
assert_eq!(0o000, mode.bits() & 0o777);
322+
}
294323
} else if cfg!(windows) {
295324
eprintln!("notice: Detected older Windows");
296325
}

0 commit comments

Comments
 (0)