-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP: Let's introduce new capable features
- Loading branch information
Showing
12 changed files
with
539 additions
and
168 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,97 @@ | ||
#![no_std] | ||
|
||
#[cfg(feature = "aya")] | ||
use aya::Pod; | ||
|
||
use bitflags::bitflags; | ||
|
||
pub enum OpenMode { | ||
Read, | ||
Write, | ||
LSeek, | ||
PRead, | ||
PWrite, | ||
Exec, | ||
WriteRestricted, | ||
Hash32, | ||
Hash64, | ||
} | ||
|
||
pub enum FileOperation { | ||
Open, | ||
Create, | ||
Delete, | ||
LinkAt, | ||
Lookup, | ||
FollowLink, | ||
} | ||
|
||
bitflags! { | ||
#[derive(PartialEq, Clone, Copy)] | ||
pub struct Access: u32 { | ||
|
||
// open modes | ||
const READ = 0b1; | ||
const WRITE = 0b10; | ||
const LSEEK = 0b100; | ||
const PREAD = 0b1000; | ||
const PWRITE = 0b10000; | ||
const EXEC = 0b100000; | ||
const WRITE_RESTRICTED = 0b1000000; | ||
const HASH32 = 0b10000000; | ||
const HASH64 = 0b100000000; | ||
|
||
// File operations | ||
const OPEN = 0b1000000000; | ||
const CREATE = 0b10000000000; | ||
const DELETE = 0b100000000000; | ||
const LINKAT = 0b1000000000000; | ||
const LOOKUP = 0b10000000000000; | ||
const FOLLOW_LINK = 0b100000000000000; | ||
} | ||
} | ||
|
||
pub type NsId = u32; | ||
|
||
impl Access { | ||
pub fn open_mode(&self) -> Option<OpenMode> { | ||
match self { | ||
&Self::READ => Some(OpenMode::Read), | ||
&Self::WRITE => Some(OpenMode::Write), | ||
&Self::LSEEK => Some(OpenMode::LSeek), | ||
&Self::PREAD => Some(OpenMode::PRead), | ||
&Self::PWRITE => Some(OpenMode::PWrite), | ||
&Self::EXEC => Some(OpenMode::Exec), | ||
&Self::WRITE_RESTRICTED => Some(OpenMode::WriteRestricted), | ||
&Self::HASH32 => Some(OpenMode::Hash32), | ||
&Self::HASH64 => Some(OpenMode::Hash64), | ||
//ignore others | ||
_ => None, | ||
} | ||
} | ||
|
||
pub fn file_operation(&self) -> Option<FileOperation> { | ||
match self { | ||
&Self::OPEN => Some(FileOperation::Open), | ||
&Self::CREATE => Some(FileOperation::Create), | ||
&Self::DELETE => Some(FileOperation::Delete), | ||
&Self::LINKAT => Some(FileOperation::LinkAt), | ||
&Self::LOOKUP => Some(FileOperation::Lookup), | ||
&Self::FOLLOW_LINK => Some(FileOperation::FollowLink), | ||
//ignore others | ||
_ => None, | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
#[repr(C)] | ||
#[derive(Clone, Copy)] | ||
pub struct Request { | ||
pub f_mode: Access, | ||
pub f_path: [u8; 8188], | ||
} | ||
|
||
#[cfg(feature = "aya")] | ||
unsafe impl Pod for Request {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
use aya_ebpf::{ | ||
helpers::{bpf_get_current_task, bpf_get_current_uid_gid, bpf_probe_read_kernel}, | ||
macros::map, | ||
maps::HashMap, | ||
programs::ProbeContext, | ||
}; | ||
|
||
use crate::ebpf_util::{get_ns_inode, TaskStructPtr, MAX_PID}; | ||
|
||
use aya_log_ebpf::{debug, info}; | ||
|
||
type Key = i32; | ||
|
||
#[map] | ||
static mut CAPABILITIES_MAP: HashMap<Key, u64> = HashMap::with_max_entries(MAX_PID, 0); | ||
#[map] | ||
static mut UID_GID_MAP: HashMap<Key, u64> = HashMap::with_max_entries(MAX_PID, 0); | ||
#[map] | ||
static mut PPID_MAP: HashMap<Key, i32> = HashMap::with_max_entries(MAX_PID, 0); | ||
#[map] | ||
static mut PNSID_NSID_MAP: HashMap<Key, u64> = HashMap::with_max_entries(MAX_PID, 0); | ||
|
||
|
||
pub fn try_capable(ctx: &ProbeContext) -> Result<u32, i64> { | ||
info!(ctx, "capable"); | ||
unsafe { | ||
let task: TaskStructPtr = bpf_get_current_task() as TaskStructPtr; | ||
debug!(ctx, "debug1"); | ||
let task = bpf_probe_read_kernel(&task)?; | ||
debug!(ctx, "debug2"); | ||
let ppid: i32 = get_ppid(task)?; | ||
debug!(ctx, "debug3"); | ||
let pid: i32 = bpf_probe_read_kernel(&(*task).pid)? as i32; | ||
debug!(ctx, "debug4"); | ||
let cap: u64 = (1 << ctx.arg::<u8>(2).unwrap()) as u64; | ||
debug!(ctx, "debug5"); | ||
let uid: u64 = bpf_get_current_uid_gid(); | ||
debug!(ctx, "debug6"); | ||
let zero = 0; | ||
let capval: u64 = *CAPABILITIES_MAP.get(&pid).unwrap_or(&zero); | ||
debug!(ctx, "debug7"); | ||
let pinum_inum: u64 = Into::<u64>::into(get_parent_ns_inode(task)?) << 32 | ||
| Into::<u64>::into(get_ns_inode(task)?); | ||
debug!(ctx, "debug8"); | ||
UID_GID_MAP | ||
.insert(&pid, &uid, 0) | ||
.expect("failed to insert uid"); | ||
debug!(ctx, "debug9"); | ||
PNSID_NSID_MAP | ||
.insert(&pid, &pinum_inum, 0) | ||
.expect("failed to insert pnsid"); | ||
debug!(ctx, "debug10"); | ||
PPID_MAP | ||
.insert(&pid, &ppid, 0) | ||
.expect("failed to insert ppid"); | ||
debug!(ctx, "debug11"); | ||
CAPABILITIES_MAP | ||
.insert(&pid, &(capval | cap), 0) | ||
.expect("failed to insert cap"); | ||
} | ||
Ok(0) | ||
} | ||
|
||
unsafe fn get_ppid(task: TaskStructPtr) -> Result<i32, i64> { | ||
let parent_task: TaskStructPtr = get_parent_task(task)?; | ||
bpf_probe_read_kernel(&(*parent_task).pid) | ||
} | ||
|
||
unsafe fn get_parent_task(task: TaskStructPtr) -> Result<TaskStructPtr, i64> { | ||
bpf_probe_read_kernel(&(*task).parent) | ||
} | ||
|
||
unsafe fn get_parent_ns_inode(task: TaskStructPtr) -> Result<u32, i64> { | ||
let parent_task: TaskStructPtr = get_parent_task(task)?; | ||
get_ns_inode(parent_task) | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
use aya_ebpf::{ | ||
helpers::{bpf_probe_read_kernel,bpf_get_current_task}, | ||
macros::map, | ||
maps::array::Array, | ||
}; | ||
use crate::open::PidPtr; | ||
use crate::vmlinux::{ns_common, nsproxy, pid_namespace, task_struct}; | ||
|
||
#[map] | ||
static mut NAMESPACE_ID: Array<u32> = Array::with_max_entries(1, 0); | ||
|
||
pub unsafe fn is_namespace_ok() -> bool { | ||
NAMESPACE_ID.get(0).map_or(false,|namespace| { | ||
let task: TaskStructPtr = bpf_get_current_task() as TaskStructPtr; | ||
let current_namespace = get_ns_inode(task); | ||
current_namespace.ok().map_or(false, |ns| ns == *namespace) | ||
}) | ||
} | ||
|
||
pub type TaskStructPtr = *mut task_struct; | ||
pub const MAX_PID: u32 = 4 * 1024 * 1024; | ||
pub const EPERM : i32 = 1; | ||
|
||
pub unsafe fn get_thread_pid(task: TaskStructPtr) -> Result<u64, i64> { | ||
let pid: PidPtr = bpf_probe_read_kernel(&(*task).thread_pid)? as PidPtr; | ||
let pid = bpf_probe_read_kernel(&(*pid).ino)? as u64; | ||
Ok(pid) | ||
} | ||
|
||
pub unsafe fn get_ns_inode(task: TaskStructPtr) -> Result<u32, i64> { | ||
let nsp: *mut nsproxy = bpf_probe_read_kernel(&(*task).nsproxy).map_err(|e| e as u32)?; | ||
let pns: *mut pid_namespace = | ||
bpf_probe_read_kernel(&(*nsp).pid_ns_for_children).map_err(|e| e as u32)?; | ||
let nsc: ns_common = bpf_probe_read_kernel(&(*pns).ns).map_err(|e| e as u32)?; | ||
bpf_probe_read_kernel(&nsc.inum) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.