Skip to content

Commit

Permalink
fix #34 error in clone probe
Browse files Browse the repository at this point in the history
Signed-off-by: qjerome <[email protected]>
  • Loading branch information
qjerome committed Feb 1, 2024
1 parent da93fa5 commit a3ce05b
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 27 deletions.
14 changes: 11 additions & 3 deletions kunai-common/src/bpf_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ pub struct TaskInfo {
pub pid: i32,
// task group uuid -> used to group tasks
pub tg_uuid: TaskUuid,
pub namespaces: Namespaces,
pub namespaces: Option<Namespaces>,
pub start_time: u64,
}

Expand Down Expand Up @@ -226,7 +226,7 @@ bpf_target_code! {
GroupLeaderMissing,
#[error("comm field is missing")]
CommMissing,
#[error("mnt_namespace")]
#[error("failed to get mnt_namespace")]
MntNamespaceFailure,
}

Expand Down Expand Up @@ -263,7 +263,15 @@ bpf_target_code! {
self.uid = task.cred().ok_or(Error::CredFieldMissing)?.uid();
self.gid = task.cred().ok_or(Error::CredFieldMissing)?.gid();

self.namespaces.mnt = core_read_kernel!(task, nsproxy, mnt_ns, ns, inum).ok_or(Error::MntNamespaceFailure)?;
if let Some(nsproxy) = core_read_kernel!(task, nsproxy){
// it may happen that under some very specific conditions nsproxy
// gets null (see https://github.com/kunai-project/kunai/issues/34)
if !nsproxy.is_null(){
self.namespaces = Some(
Namespaces { mnt: core_read_kernel!(nsproxy, mnt_ns, ns, inum).ok_or(Error::MntNamespaceFailure)? }
);
}
}

Ok(())
}
Expand Down
77 changes: 55 additions & 22 deletions kunai/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,14 +372,39 @@ impl EventProcessor {
}

#[inline]
fn get_hashes_with_ns(&mut self, ns: Namespace, p: &kunai_common::path::Path) -> Hashes {
match self.cache.get_or_cache_in_ns(ns, p) {
Ok(h) => h,
Err(e) => Hashes {
fn get_hashes_with_ns(
&mut self,
ns: Option<Namespace>,
p: &kunai_common::path::Path,
) -> Hashes {
if let Some(ns) = ns {
match self.cache.get_or_cache_in_ns(ns, p) {
Ok(h) => h,
Err(e) => Hashes {
file: p.to_path_buf(),
error: Some(format!("{e}")),
..Default::default()
},
}
} else {
Hashes {
file: p.to_path_buf(),
error: Some(format!("{e}")),
error: Some("unknown namespace".into()),
..Default::default()
},
}
}
}

#[inline(always)]
/// method acting as a central place to get the mnt namespace of a
/// task and printing out an error if not found
fn task_mnt_ns(ei: &bpf_events::EventInfo) -> Option<Namespace> {
match ei.process.namespaces {
Some(ns) => Some(Namespace::mnt(ns.mnt)),
None => {
error!("task namespace must be known");
None
}
}
}

Expand All @@ -391,18 +416,18 @@ impl EventProcessor {
) -> UserEvent<ExecveData> {
let ancestors = self.get_ancestors(&info);

let mnt_ns = Namespace::mnt(event.info.process.namespaces.mnt);
let opt_mnt_ns = Self::task_mnt_ns(&event.info);

let mut data = ExecveData {
ancestors: ancestors.join("|"),
parent_exe: self.get_parent_image(&info),
command_line: event.data.argv.to_command_line(),
exe: self.get_hashes_with_ns(mnt_ns, &event.data.executable),
exe: self.get_hashes_with_ns(opt_mnt_ns, &event.data.executable),
interpreter: None,
};

if event.data.executable != event.data.interpreter {
data.interpreter = Some(self.get_hashes_with_ns(mnt_ns, &event.data.interpreter))
data.interpreter = Some(self.get_hashes_with_ns(opt_mnt_ns, &event.data.interpreter))
}

UserEvent::new(data, info)
Expand Down Expand Up @@ -456,8 +481,8 @@ impl EventProcessor {
event: &bpf_events::MmapExecEvent,
) -> UserEvent<kunai::events::MmapExecData> {
let filename = event.data.filename;
let mnt_ns = Namespace::mnt(event.info.process.namespaces.mnt);
let mmapped_hashes = self.get_hashes_with_ns(mnt_ns, &filename);
let opt_mnt_ns = Self::task_mnt_ns(&event.info);
let mmapped_hashes = self.get_hashes_with_ns(opt_mnt_ns, &filename);

let ck = info.task_key();

Expand Down Expand Up @@ -839,12 +864,12 @@ impl EventProcessor {

#[inline]
fn handle_hash_event(&mut self, info: StdEventInfo, event: &bpf_events::HashEvent) {
let mnt_ns = Namespace::mnt(info.info.process.namespaces.mnt);
self.get_hashes_with_ns(mnt_ns, &event.data.path);
let opt_mnt_ns = Self::task_mnt_ns(&info.info);
self.get_hashes_with_ns(opt_mnt_ns, &event.data.path);
}

fn build_std_event_info(&mut self, i: bpf_events::EventInfo) -> StdEventInfo {
let mnt_ns = Namespace::mnt(i.process.namespaces.mnt);
let opt_mnt_ns = Self::task_mnt_ns(&i);

let std_info = StdEventInfo::from_bpf(i, self.random);

Expand All @@ -857,11 +882,13 @@ impl EventProcessor {

let mut container = None;

if mnt_ns != self.system_info.mount_ns {
container = Some(kunai::info::ContainerInfo {
name: self.cache.get_hostname(mnt_ns).unwrap_or("?".into()),
ty: cd.and_then(|cd| cd.container),
});
if let Some(mnt_ns) = opt_mnt_ns {
if mnt_ns != self.system_info.mount_ns {
container = Some(kunai::info::ContainerInfo {
name: self.cache.get_hostname(mnt_ns).unwrap_or("?".into()),
ty: cd.and_then(|cd| cd.container),
});
}
}

std_info.with_additional_info(AdditionalInfo { host, container })
Expand Down Expand Up @@ -949,10 +976,16 @@ impl EventProcessor {
}

let pid = i.process.tgid;
let ns = Namespace::mnt(i.process.namespaces.mnt);

if let Err(e) = self.cache.cache_ns(pid, ns) {
debug!("failed to cache namespace pid={pid} ns={ns}: {e}");
if let Some(ns) = i.process.namespaces {
let mnt = Namespace::mnt(ns.mnt);
if let Err(e) = self.cache.cache_ns(pid, mnt) {
debug!("failed to cache namespace pid={pid} ns={mnt}: {e}");
}
} else {
// the few cases where we expect namespaces to be unknown
// is for parent's task
error!("namespaces are supposed to be known for task")
}

let std_info = self.build_std_event_info(*i);
Expand Down
7 changes: 5 additions & 2 deletions kunai/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ pub struct TaskSection {
guuid: String,
uid: u32,
gid: u32,
namespaces: NamespaceInfo,
namespaces: Option<NamespaceInfo>,
#[serde(serialize_with = "serialize_to_hex")]
flags: u32,
}
Expand All @@ -107,7 +107,10 @@ impl From<kunai_common::bpf_events::TaskInfo> for TaskSection {
guuid: value.tg_uuid.into_uuid().hyphenated().to_string(),
uid: value.uid,
gid: value.gid,
namespaces: value.namespaces.into(),
namespaces: match value.namespaces {
Some(ns) => Some(ns.into()),
_ => None,
},
flags: value.flags,
}
}
Expand Down

0 comments on commit a3ce05b

Please sign in to comment.