keylime-agent-rust/rust-keylime-set-supplementary-groups.patch
Anderson Toshiyuki Sasaki c7b2752739 Backport some upstream bug fixes
- Set supplementary groups when dropping privileges
- Show more descriptive error messages on missing files errors
- Create /usr/libexec/keylime directory

Related: rhbz#2084552

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2022-07-01 14:11:24 +02:00

163 lines
5.3 KiB
Diff

From 4ec807b1bbcfaa67f85d0c2659b1f439c2f540b4 Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Fri, 24 Jun 2022 16:25:54 +0200
Subject: [PATCH] permissions: Set supplementary groups when dropping
privileges
This allows the agent to run with the user primary group and have the
access given by the supplementary groups.
Fixes: #414
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
---
src/permissions.rs | 70 ++++++++++++++++++++++++++++++++++------------
1 file changed, 52 insertions(+), 18 deletions(-)
diff --git a/src/permissions.rs b/src/permissions.rs
index 279a6dd..86e3fae 100644
--- a/src/permissions.rs
+++ b/src/permissions.rs
@@ -2,7 +2,7 @@
// Copyright 2021 Keylime Authors
use crate::error::{Error, Result};
-use libc::{gid_t, uid_t};
+use libc::{c_char, c_int, gid_t, uid_t};
use log::*;
use std::os::unix::ffi::OsStrExt;
use std::{
@@ -13,10 +13,9 @@ use std::{
ptr,
};
-#[derive(Debug)]
pub(crate) struct UserIds {
- uid: uid_t,
- gid: gid_t,
+ passwd: libc::passwd,
+ group: libc::group,
}
pub(crate) fn get_gid() -> gid_t {
@@ -47,14 +46,14 @@ impl TryFrom<&str> for UserIds {
let group = parts[1];
// Get gid from group name
- let gid = if let Ok(g_cstr) = CString::new(group.as_bytes()) {
+ let grnam = if let Ok(g_cstr) = CString::new(group.as_bytes()) {
let p = unsafe { libc::getgrnam(g_cstr.as_ptr()) };
if p.is_null() {
let e = io::Error::last_os_error();
error!("Could not get group {}: {}", group, e);
return Err(Error::Conversion(e.to_string()));
}
- unsafe { (*p).gr_gid }
+ unsafe { (*p) }
} else {
return Err(Error::Conversion(format!(
"Failed to convert {} to CString",
@@ -63,14 +62,14 @@ impl TryFrom<&str> for UserIds {
};
// Get uid from user name
- let uid = if let Ok(u_cstr) = CString::new(user.as_bytes()) {
+ let passwd = if let Ok(u_cstr) = CString::new(user.as_bytes()) {
let p = unsafe { libc::getpwnam(u_cstr.as_ptr()) };
if p.is_null() {
let e = io::Error::last_os_error();
error!("Could not get user {}: {}", user, e);
return Err(Error::Conversion(e.to_string()));
}
- unsafe { (*p).pw_uid }
+ unsafe { (*p) }
} else {
return Err(Error::Conversion(format!(
"Failed to convert {} to CString",
@@ -78,7 +77,10 @@ impl TryFrom<&str> for UserIds {
)));
};
- Ok(UserIds { uid, gid })
+ Ok(UserIds {
+ passwd,
+ group: grnam,
+ })
}
}
@@ -88,22 +90,51 @@ impl TryFrom<&str> for UserIds {
pub(crate) fn run_as(user_group: &str) -> Result<()> {
let ids: UserIds = user_group.try_into()?;
- // Drop supplementary groups
- if unsafe { libc::setgroups(0, ptr::null()) } != 0 {
+ // Set gid
+ if unsafe { libc::setgid(ids.group.gr_gid) } != 0 {
let e = io::Error::last_os_error();
- error!("Could not drop supplementary groups: {}", e);
+ error!("Could not set group id: {}", e);
return Err(Error::Permission);
}
- // Set gid
- if unsafe { libc::setgid(ids.gid) } != 0 {
+ // Get list of supplementary groups
+ let mut sup_groups: [gid_t; 32] = [0u32; 32];
+ let mut ngroups: c_int = 32;
+ if unsafe {
+ libc::getgrouplist(
+ ids.passwd.pw_name,
+ ids.group.gr_gid,
+ sup_groups.as_mut_ptr(),
+ &mut ngroups,
+ )
+ } < 0
+ {
+ // Allocate a Vec and try again
+ let mut sup_groups: Vec<gid_t> = Vec::with_capacity(ngroups as usize);
+ if unsafe {
+ libc::getgrouplist(
+ ids.passwd.pw_name,
+ ids.group.gr_gid,
+ sup_groups.as_mut_ptr(),
+ &mut ngroups,
+ )
+ } < 0
+ {
+ error!("Could not get list of supplementary groups");
+ return Err(Error::Permission);
+ }
+ }
+
+ // Set supplementary groups
+ if unsafe { libc::setgroups(ngroups as usize, sup_groups.as_ptr()) } != 0
+ {
let e = io::Error::last_os_error();
- error!("Could not set group id: {}", e);
+ error!("Could not set supplementary groups: {}", e);
return Err(Error::Permission);
}
// Set uid
- if unsafe { libc::setuid(ids.uid) } != 0 {
+ if unsafe { libc::setuid(ids.passwd.pw_uid) } != 0 {
let e = io::Error::last_os_error();
error!("Could not set user id: {}", e);
return Err(Error::Permission);
@@ -126,9 +157,12 @@ pub(crate) fn chown(user_group: &str, path: &Path) -> Result<()> {
return Err(Error::Permission);
}
- // change directory owner to root
+ // change directory owner
let c_path = CString::new(path.as_os_str().as_bytes())?;
- if unsafe { libc::chown(c_path.as_ptr(), ids.uid, ids.gid) } != 0 {
+ if unsafe {
+ libc::chown(c_path.as_ptr(), ids.passwd.pw_uid, ids.group.gr_gid)
+ } != 0
+ {
error!("Failed to change file {} owner.", path.display());
return Err(Error::Permission);
}