summary refs log tree commit diff
path: root/sys_util
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor@chromium.org>2019-03-06 10:56:51 -0800
committerchrome-bot <chrome-bot@chromium.org>2019-03-08 21:20:23 -0800
commit710060744866cde8cada39caa8461a7194e4869b (patch)
tree75e7590ddb729c2780f94f605f219e80c4220b5e /sys_util
parent766f8108b39ab55fcb05bf8de249ea6170536599 (diff)
downloadcrosvm-710060744866cde8cada39caa8461a7194e4869b.tar
crosvm-710060744866cde8cada39caa8461a7194e4869b.tar.gz
crosvm-710060744866cde8cada39caa8461a7194e4869b.tar.bz2
crosvm-710060744866cde8cada39caa8461a7194e4869b.tar.lz
crosvm-710060744866cde8cada39caa8461a7194e4869b.tar.xz
crosvm-710060744866cde8cada39caa8461a7194e4869b.tar.zst
crosvm-710060744866cde8cada39caa8461a7194e4869b.zip
Drop capabilities before spawning any vcpu thread
In case crosvm starts with elevated capabilities (for example, we need
to start with CAP_SETGID to be able to map additional gids into plugin
jail), we should drop them before spawning VCPU threads.

BUG=b:117989168
TEST=Start plugin via concierge_client and verify the process does not
     have any effective or permitted privileges.
     tast run [] 'vm.*'

Change-Id: Ia1e80bfe19b296936d77fe9ffeda361211b41eed
Reviewed-on: https://chromium-review.googlesource.com/1506296
Commit-Ready: Dmitry Torokhov <dtor@chromium.org>
Tested-by: Dmitry Torokhov <dtor@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
Diffstat (limited to 'sys_util')
-rw-r--r--sys_util/src/capabilities.rs42
-rw-r--r--sys_util/src/lib.rs2
2 files changed, 44 insertions, 0 deletions
diff --git a/sys_util/src/capabilities.rs b/sys_util/src/capabilities.rs
new file mode 100644
index 0000000..0117ce4
--- /dev/null
+++ b/sys_util/src/capabilities.rs
@@ -0,0 +1,42 @@
+// Copyright 2019 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+extern crate libc;
+
+use libc::{c_int, c_void};
+use {errno_result, Result};
+
+#[allow(non_camel_case_types)]
+type cap_t = *mut c_void;
+
+#[link(name = "cap")]
+extern "C" {
+    fn cap_init() -> cap_t;
+    fn cap_free(ptr: *mut c_void) -> c_int;
+    fn cap_set_proc(cap: cap_t) -> c_int;
+}
+
+/// Drops all capabilities (permitted, inheritable, and effective) from the current process.
+pub fn drop_capabilities() -> Result<()> {
+    unsafe {
+        // Safe because we do not actually manipulate any memory handled by libcap
+        // and we check errors.
+        let caps = cap_init();
+        if caps.is_null() {
+            return errno_result();
+        }
+
+        // Freshly initialized capabilities do not have any bits set, so applying them
+        // will drop all capabilities from the process.
+        // Safe because we will check the result and otherwise do not touch the memory.
+        let ret = cap_set_proc(caps);
+        // We need to free capabilities regardless of success of the operation above.
+        cap_free(caps);
+        // Now check if we managed to apply (drop) capabilities.
+        if ret < 0 {
+            return errno_result();
+        }
+    }
+    Ok(())
+}
diff --git a/sys_util/src/lib.rs b/sys_util/src/lib.rs
index 29aa489..dcc7390 100644
--- a/sys_util/src/lib.rs
+++ b/sys_util/src/lib.rs
@@ -18,6 +18,7 @@ pub mod handle_eintr;
 pub mod ioctl;
 #[macro_use]
 pub mod syslog;
+mod capabilities;
 mod clock;
 mod errno;
 mod eventfd;
@@ -43,6 +44,7 @@ mod terminal;
 mod timerfd;
 mod write_zeroes;
 
+pub use capabilities::drop_capabilities;
 pub use clock::{Clock, FakeClock};
 use errno::errno_result;
 pub use errno::{Error, Result};