Skip to content

Commit

Permalink
Use rustix to replace some unsafe calls
Browse files Browse the repository at this point in the history
  • Loading branch information
yujincheng08 committed Jan 31, 2024
1 parent 4b1fb12 commit c1a2cbf
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 28 deletions.
32 changes: 17 additions & 15 deletions userspace/ksud/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions userspace/ksud/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ hole-punch = { git = "https://github.com/tiann/hole-punch" }

[target.'cfg(any(target_os = "android", target_os = "linux"))'.dependencies]
sys-mount = { git = "https://github.com/tiann/sys-mount", branch = "loopfix" }
rustix = { version = "0.38", features = ["all-apis"] }
# some android specific dependencies which compiles under unix are also listed here for convenience of coding
android-properties = { version = "0.2.2", features = ["bionic-deprecated"] }
procfs = "0.16"
Expand Down
1 change: 0 additions & 1 deletion userspace/ksud/src/event.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use anyhow::{bail, Context, Result};
use log::{info, warn};
use std::path::PathBuf;
use std::{collections::HashMap, path::Path};

use crate::module::prune_modules;
Expand Down
17 changes: 14 additions & 3 deletions userspace/ksud/src/ksu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ use crate::{
utils::{self, umask},
};

#[cfg(any(target_os = "linux", target_os = "android"))]
use rustix::{
process::getuid,
thread::{set_thread_res_gid, set_thread_res_uid, Gid, Uid},
};

pub const KERNEL_SU_OPTION: u32 = 0xDEAD_BEEF;

const CMD_GRANT_ROOT: u64 = 0;
Expand Down Expand Up @@ -65,8 +71,13 @@ fn set_identity(uid: u32, gid: u32, groups: &[u32]) {
if !groups.is_empty() {
libc::setgroups(groups.len(), groups.as_ptr());
}
libc::setresgid(gid, gid, gid);
libc::setresuid(uid, uid, uid);
}
#[cfg(any(target_os = "linux", target_os = "android"))]
{
let gid = unsafe { Gid::from_raw(gid) };
let uid = unsafe { Uid::from_raw(uid) };
set_thread_res_gid(gid, gid, gid).ok();
set_thread_res_uid(uid, uid, uid).ok();
}
}

Expand Down Expand Up @@ -203,7 +214,7 @@ pub fn root_shell() -> Result<()> {
}

// use current uid if no user specified, these has been done in kernel!
let mut uid = unsafe { libc::getuid() };
let mut uid = getuid().as_raw();
if free_idx < matches.free.len() {
let name = &matches.free[free_idx];
uid = unsafe {
Expand Down
23 changes: 14 additions & 9 deletions userspace/ksud/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ use std::os::unix::prelude::PermissionsExt;
use hole_punch::*;
use std::io::{Read, Seek, SeekFrom};

#[cfg(any(target_os = "linux", target_os = "android"))]
use rustix::{
process,
thread::{move_into_link_name_space, unshare, LinkNameSpaceType, UnshareFlags},
};

pub fn ensure_clean_dir(dir: &str) -> Result<()> {
let path = Path::new(dir);
log::debug!("ensure_clean_dir: {}", path.display());
Expand Down Expand Up @@ -115,24 +121,23 @@ pub fn get_zip_uncompressed_size(zip_path: &str) -> Result<u64> {

#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn switch_mnt_ns(pid: i32) -> Result<()> {
use anyhow::ensure;
use std::os::fd::AsRawFd;
use rustix::{
fd::AsFd,
fs::{open, Mode, OFlags},
};
let path = format!("/proc/{pid}/ns/mnt");
let fd = std::fs::File::open(path)?;
let fd = open(path, OFlags::RDONLY, Mode::from_raw_mode(0))?;
let current_dir = std::env::current_dir();
let ret = unsafe { libc::setns(fd.as_raw_fd(), libc::CLONE_NEWNS) };
move_into_link_name_space(fd.as_fd(), Some(LinkNameSpaceType::Mount))?;
if let std::result::Result::Ok(current_dir) = current_dir {
let _ = std::env::set_current_dir(current_dir);
}
ensure!(ret == 0, "switch mnt ns failed");
Ok(())
}

#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn unshare_mnt_ns() -> Result<()> {
use anyhow::ensure;
let ret = unsafe { libc::unshare(libc::CLONE_NEWNS) };
ensure!(ret == 0, "unshare mnt ns failed");
unshare(UnshareFlags::NEWNS)?;
Ok(())
}

Expand Down Expand Up @@ -164,7 +169,7 @@ pub fn switch_cgroups() {

#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn umask(mask: u32) {
unsafe { libc::umask(mask) };
process::umask(rustix::fs::Mode::from_raw_mode(mask));
}

#[cfg(not(any(target_os = "linux", target_os = "android")))]
Expand Down

0 comments on commit c1a2cbf

Please sign in to comment.