devices: virtio: Skip setting SECBIT_NO_SETUID_FIXUP for regular user.

When running crosvm as regular user, virtio fs worker can't change
uid. Skip setting SECBIT_NO_SETUID_FIXUP since it's unnecessary.

BUG=b:231324557
TEST=crosvm run --shared-dir "/:mtdfake:type=fs:cache=always" \
     -p "rootfstype=virtiofs root=mtdfake ro init=/bin/sh" vmlinux

Change-Id: Id58e0f98d93e261cd8b808aae1ac62c95d09ea20
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5178253
Auto-Submit: Lepton Wu <lepton@chromium.org>
Reviewed-by: Dennis Kempin <denniskempin@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Lepton Wu <lepton@chromium.org>
This commit is contained in:
Lepton Wu 2024-01-08 15:00:29 -08:00 committed by crosvm LUCI
parent 650fbaf7fc
commit eeea9b93d2
6 changed files with 34 additions and 15 deletions

View file

@ -74,6 +74,9 @@ pub enum Error {
/// Error happened in FUSE.
#[error("fuse error: {0}")]
FuseError(fuse::Error),
/// Failed to get the uids for the worker thread.
#[error("failed to get uids for the worker thread: {0}")]
GetResuid(SysError),
/// Failed to get the securebits for the worker thread.
#[error("failed to get securebits for the worker thread: {0}")]
GetSecurebits(SysError),

View file

@ -183,24 +183,36 @@ impl<F: FileSystem + Sync> Worker<F> {
}
pub fn run(&mut self, kill_evt: Event, watch_resample_event: bool) -> Result<()> {
// We need to set the no setuid fixup secure bit so that we don't drop capabilities when
// changing the thread uid/gid. Without this, creating new entries can fail in some corner
// cases.
const SECBIT_NO_SETUID_FIXUP: i32 = 1 << 2;
let mut ruid: libc::uid_t = 0;
let mut euid: libc::uid_t = 0;
let mut suid: libc::uid_t = 0;
// SAFETY: Safe because this doesn't modify any memory and we check the return value.
syscall!(unsafe { libc::getresuid(&mut ruid, &mut euid, &mut suid) })
.map_err(Error::GetResuid)?;
let mut securebits = syscall!(
// SAFETY: Safe because this doesn't modify any memory and we check the return value.
unsafe { libc::prctl(libc::PR_GET_SECUREBITS) }
)
.map_err(Error::GetSecurebits)?;
// Only need to set SECBIT_NO_SETUID_FIXUP for threads which could change uid.
if ruid == 0 || ruid != euid || ruid != suid {
// We need to set the no setuid fixup secure bit so that we don't drop capabilities when
// changing the thread uid/gid. Without this, creating new entries can fail in some
// corner cases.
const SECBIT_NO_SETUID_FIXUP: i32 = 1 << 2;
securebits |= SECBIT_NO_SETUID_FIXUP;
let mut securebits = syscall!(
// SAFETY:
// Safe because this doesn't modify any memory and we check the return value.
unsafe { libc::prctl(libc::PR_GET_SECUREBITS) }
)
.map_err(Error::GetSecurebits)?;
syscall!(
// SAFETY: Safe because this doesn't modify any memory and we check the return value.
unsafe { libc::prctl(libc::PR_SET_SECUREBITS, securebits) }
)
.map_err(Error::SetSecurebits)?;
securebits |= SECBIT_NO_SETUID_FIXUP;
syscall!(
// SAFETY:
// Safe because this doesn't modify any memory and we check the return value.
unsafe { libc::prctl(libc::PR_SET_SECUREBITS, securebits) }
)
.map_err(Error::SetSecurebits)?;
}
// To avoid extra locking, unshare filesystem attributes from parent. This includes the
// current working directory and umask.

View file

@ -27,6 +27,7 @@ getdents64: 1
getegid: 1
geteuid: 1
getrandom: 1
getresuid: 1
# Use constants for verity ioctls since minijail doesn't understand them yet.
# 0x40806685 = FS_IOC_ENABLE_VERITY
# 0xc0046686 = FS_IOC_MEASURE_VERITY

View file

@ -28,6 +28,7 @@ getdents64: 1
getegid32: 1
geteuid32: 1
getrandom: 1
getresuid: 1
# Use constants for verity ioctls since minijail doesn't understand them yet.
# 0x40806685 = FS_IOC_ENABLE_VERITY
# 0xc0046686 = FS_IOC_MEASURE_VERITY

View file

@ -27,6 +27,7 @@ getdents64: 1
getegid: 1
geteuid: 1
getrandom: 1
getresuid: 1
# Use constants for verity ioctls since minijail doesn't understand them yet.
# 0x40806685 = FS_IOC_ENABLE_VERITY
# 0xc0046686 = FS_IOC_MEASURE_VERITY

View file

@ -26,6 +26,7 @@ getdents64: 1
getegid: 1
geteuid: 1
getrandom: 1
getresuid: 1
# Use constants for verity ioctls since minijail doesn't understand them yet.
# 0x40806685 = FS_IOC_ENABLE_VERITY
# 0xc0046686 = FS_IOC_MEASURE_VERITY