summary refs log tree commit diff
path: root/src/linux.rs
diff options
context:
space:
mode:
authorChirantan Ekbote <chirantan@chromium.org>2019-12-09 14:58:54 +0900
committerCommit Bot <commit-bot@chromium.org>2019-12-09 23:39:16 +0000
commitaa77ea40454c460a7189860f1ea146c45e444dad (patch)
tree1aa1a8544a2ad434000884c52ec334ecf2ceaa64 /src/linux.rs
parentc4a871fb70597aa6ce1773ec905c4704be519940 (diff)
downloadcrosvm-aa77ea40454c460a7189860f1ea146c45e444dad.tar
crosvm-aa77ea40454c460a7189860f1ea146c45e444dad.tar.gz
crosvm-aa77ea40454c460a7189860f1ea146c45e444dad.tar.bz2
crosvm-aa77ea40454c460a7189860f1ea146c45e444dad.tar.lz
crosvm-aa77ea40454c460a7189860f1ea146c45e444dad.tar.xz
crosvm-aa77ea40454c460a7189860f1ea146c45e444dad.tar.zst
crosvm-aa77ea40454c460a7189860f1ea146c45e444dad.zip
linux.rs: Don't use /proc/sys/fs/file-max
Don't use /proc/sys/fs/file-max when setting the max open file limit for
the virtio-fs device.  This will fail when the value is larger than the
hard limit set for the crosvm process, unless it also has CAP_SYS_ADMIN
in the initial namespace.

Instead, just use the hard limit as returned by `prlimit64`.  Increasing
the soft limit up to the hard limit is allowed even for completely
unprivileged processes.  It is up to the process that spawned crosvm to
ensure that the hard limit is high enough that the virtio-fs server will
not run out of fds.

BUG=b:142344095
TEST=Start a termina VM with a virtio-fs device after applying
     CL:1939193

Change-Id: I4fb4c33ffe6378ed3109fddcb0fc2bf3da850252
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1957767
Tested-by: Chirantan Ekbote <chirantan@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Auto-Submit: Chirantan Ekbote <chirantan@chromium.org>
Commit-Queue: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Diffstat (limited to 'src/linux.rs')
-rw-r--r--src/linux.rs18
1 files changed, 12 insertions, 6 deletions
diff --git a/src/linux.rs b/src/linux.rs
index 1c606b9..0cc341d 100644
--- a/src/linux.rs
+++ b/src/linux.rs
@@ -18,6 +18,7 @@ use std::num::ParseIntError;
 use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
 use std::os::unix::net::UnixStream;
 use std::path::{Path, PathBuf};
+use std::ptr;
 use std::str;
 use std::sync::{Arc, Barrier};
 use std::thread;
@@ -290,12 +291,17 @@ impl AsRawFd for TaggedControlSocket {
 }
 
 fn get_max_open_files() -> Result<libc::rlim64_t> {
-    let mut buf = String::with_capacity(32);
-    File::open("/proc/sys/fs/file-max")
-        .and_then(|mut f| f.read_to_string(&mut buf))
-        .map_err(Error::GetMaxOpenFiles)?;
-
-    Ok(buf.trim().parse().map_err(Error::ParseMaxOpenFiles)?)
+    let mut buf = mem::MaybeUninit::<libc::rlimit64>::zeroed();
+
+    // Safe because this will only modify `buf` and we check the return value.
+    let res = unsafe { libc::prlimit64(0, libc::RLIMIT_NOFILE, ptr::null(), buf.as_mut_ptr()) };
+    if res == 0 {
+        // Safe because the kernel guarantees that the struct is fully initialized.
+        let limit = unsafe { buf.assume_init() };
+        Ok(limit.rlim_max)
+    } else {
+        Err(Error::GetMaxOpenFiles(io::Error::last_os_error()))
+    }
 }
 
 fn create_base_minijail(