Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sigquit Feature, Event, Collector implementation #189

Merged
merged 6 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package de.amosproj3.ziofa.api.configuration

import de.amosproj3.ziofa.client.JniReferencesConfig
import de.amosproj3.ziofa.client.SysSendmsgConfig
import de.amosproj3.ziofa.client.SysSigquitConfig
import de.amosproj3.ziofa.client.UprobeConfig
import de.amosproj3.ziofa.client.VfsWriteConfig
import kotlinx.coroutines.flow.Flow
Expand Down Expand Up @@ -35,6 +36,7 @@ interface LocalConfigurationAccess {
sendMessageFeature: SysSendmsgConfig? = null,
uprobesFeature: List<UprobeConfig>? = listOf(),
jniReferencesFeature: JniReferencesConfig? = null,
sysSigquitFeature: SysSigquitConfig? = null,
)

/** Submit the local configuration to the backend. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package de.amosproj3.ziofa.bl.configuration

import de.amosproj3.ziofa.client.JniReferencesConfig
import de.amosproj3.ziofa.client.SysSendmsgConfig
import de.amosproj3.ziofa.client.SysSigquitConfig
import de.amosproj3.ziofa.client.UprobeConfig
import de.amosproj3.ziofa.client.VfsWriteConfig

Expand Down Expand Up @@ -50,3 +51,11 @@ fun JniReferencesConfig?.updatePIDs(
val config = this ?: JniReferencesConfig(listOf())
return config.copy(pids = config.pids.plus(pidsToAdd).minus(pidsToRemove.toSet()))
}

fun SysSigquitConfig?.updatePIDs(
pidsToAdd: List<UInt> = listOf(),
pidsToRemove: List<UInt> = listOf(),
): SysSigquitConfig {
val config = this ?: SysSigquitConfig(listOf())
return config.copy(pids = config.pids.plus(pidsToAdd).minus(pidsToRemove.toSet()))
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import de.amosproj3.ziofa.client.ClientFactory
import de.amosproj3.ziofa.client.Configuration
import de.amosproj3.ziofa.client.JniReferencesConfig
import de.amosproj3.ziofa.client.SysSendmsgConfig
import de.amosproj3.ziofa.client.SysSigquitConfig
import de.amosproj3.ziofa.client.UprobeConfig
import de.amosproj3.ziofa.client.VfsWriteConfig
import de.amosproj3.ziofa.ui.shared.merge
Expand Down Expand Up @@ -66,6 +67,7 @@ class ConfigurationManager(val clientFactory: ClientFactory) :
sendMessageFeature: SysSendmsgConfig?,
uprobesFeature: List<UprobeConfig>?,
jniReferencesFeature: JniReferencesConfig?,
sysSigquitFeature: SysSigquitConfig?,
) {
_localConfiguration.update { prev ->
Timber.e("changeFeatureConfigurationForPIDs.prev $prev")
Expand All @@ -84,6 +86,7 @@ class ConfigurationManager(val clientFactory: ClientFactory) :
sysSendmsg = previousConfiguration.merge(sendMessageFeature, enable),
uprobes = previousConfiguration.merge(uprobesFeature, enable),
jniReferences = previousConfiguration.merge(jniReferencesFeature, enable),
sysSigquit = previousConfiguration.merge(sysSigquitFeature, enable),
)
.also { Timber.i("new local configuration = $it") }
.let { ConfigurationUpdate.Valid(it) }
Expand All @@ -102,7 +105,7 @@ class ConfigurationManager(val clientFactory: ClientFactory) :

override fun reset() {
runBlocking {
client?.setConfiguration(Configuration(null, null, listOf(), null))
client?.setConfiguration(Configuration(null, null, listOf(), null, null))
updateBothConfigurations(getFromBackend())
}
}
Expand All @@ -129,6 +132,7 @@ class ConfigurationManager(val clientFactory: ClientFactory) :
sysSendmsg = null,
uprobes = listOf(),
jniReferences = null,
sysSigquit = null,
)
)
ConfigurationUpdate.Valid(client!!.getConfiguration())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import de.amosproj3.ziofa.bl.configuration.updateUProbes
import de.amosproj3.ziofa.client.Configuration
import de.amosproj3.ziofa.client.JniReferencesConfig
import de.amosproj3.ziofa.client.SysSendmsgConfig
import de.amosproj3.ziofa.client.SysSigquitConfig
import de.amosproj3.ziofa.client.UprobeConfig
import de.amosproj3.ziofa.client.VfsWriteConfig

Expand Down Expand Up @@ -43,3 +44,11 @@ fun Configuration.merge(jniReferencesConfig: JniReferencesConfig?, enable: Boole
pidsToRemove = if (!enable) requestedChanges.pids else listOf(),
)
} ?: this.jniReferences

fun Configuration.merge(sysSigquitConfig: SysSigquitConfig?, enable: Boolean) =
sysSigquitConfig?.let { requestedChanges ->
this.sysSigquit.updatePIDs(
pidsToAdd = if (enable) requestedChanges.pids else listOf(),
pidsToRemove = if (!enable) requestedChanges.pids else listOf(),
)
} ?: this.sysSigquit
10 changes: 10 additions & 0 deletions frontend/client/src/main/java/de/amosproj3/ziofa/client/Client.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ data class Configuration(
val sysSendmsg: SysSendmsgConfig?,
val uprobes: List<UprobeConfig>,
val jniReferences: JniReferencesConfig?,
val sysSigquit: SysSigquitConfig?,
)

data class VfsWriteConfig(val entries: Map<UInt, ULong>)
Expand All @@ -22,6 +23,8 @@ data class UprobeConfig(val fnName: String, val offset: ULong, var target: Strin

data class JniReferencesConfig(val pids: List<UInt>)

data class SysSigquitConfig(val pids: List<UInt>)

sealed class Event {
data class VfsWrite(
val pid: UInt,
Expand Down Expand Up @@ -52,6 +55,13 @@ sealed class Event {
DeleteGlobalRef,
}
}

data class SysSigquit(
val pid: UInt,
val tid: UInt,
val timeStamp: ULong,
val targetPid: ULong,
) : Event()
}

data class Process(val pid: UInt, val ppid: UInt, val state: String, val cmd: Command?)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ object RustClient : Client {
sysSendmsg = SysSendmsgConfig(mapOf(1234u to 30000u, 43124u to 20000u)),
uprobes = listOf(),
jniReferences = JniReferencesConfig(pids = listOf()),
sysSigquit = SysSigquitConfig(pids = listOf()),
)

override suspend fun serverCount(): Flow<UInt> = flow {
Expand Down Expand Up @@ -119,6 +120,16 @@ object RustClient : Client {
)
)
}
configuration.sysSigquit?.pids?.forEach {
emit(
Event.SysSigquit(
pid = it,
tid = 1234u,
timeStamp = 12312412u,
targetPid = 12874u,
)
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ private fun uniffi.shared.Event.into() =
JniMethodName.UNDEFINED -> null
},
)
is EventData.SysSigquit ->
Event.SysSigquit(
pid = d.v1.pid,
tid = d.v1.tid,
timeStamp = d.v1.timeStamp,
targetPid = d.v1.targetPid,
)
null -> null
}

Expand All @@ -81,6 +88,7 @@ private fun uniffi.shared.Configuration.into() =
)
},
jniReferences = jniReferences?.let { JniReferencesConfig(pids = it.pids) },
sysSigquit = sysSigquit?.let { SysSigquitConfig(pids = it.pids) },
)

private fun Configuration.into() =
Expand All @@ -97,6 +105,7 @@ private fun Configuration.into() =
)
},
jniReferences = jniReferences?.let { uniffi.shared.JniReferencesConfig(it.pids) },
sysSigquit = sysSigquit?.let { uniffi.shared.SysSigquitConfig(it.pids) },
)

private fun uniffi.shared.StringResponse.into() = StringResponse(name)
Expand Down
21 changes: 17 additions & 4 deletions rust/backend/daemon/src/collector/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
//
// SPDX-License-Identifier: MIT

use backend_common::{JNICall, JNIMethodName, SysSendmsgCall, VfsWriteCall};
use shared::ziofa::{Event, JniReferencesEvent, SysSendmsgEvent, VfsWriteEvent};
use shared::ziofa::event::{EventData};
use shared::ziofa::jni_references_event::{JniMethodName};
use backend_common::{JNICall, JNIMethodName, SysSendmsgCall, VfsWriteCall, SysSigquitCall};
use shared::ziofa::{Event, JniReferencesEvent, SysSendmsgEvent, VfsWriteEvent, SysSigquitEvent};
use shared::ziofa::event::EventData;
use shared::ziofa::jni_references_event::JniMethodName;
mod ring_buf;
mod supervisor;
mod event_dipatcher;
Expand Down Expand Up @@ -63,4 +63,17 @@ impl IntoEvent for JNICall {
}))
}
}
}

impl IntoEvent for SysSigquitCall {
fn into_event(self) -> Event {
Event {
event_data: Some(EventData::SysSigquit(SysSigquitEvent {
pid: self.pid,
tid: self.tid,
time_stamp: self.time_stamp,
target_pid: self.target_pid,
}))
}
}
}
4 changes: 3 additions & 1 deletion rust/backend/daemon/src/collector/supervisor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ enum CollectorT {
VfsWrite,
SysSendmsg,
JniCall,
SysSigquit,
}

pub struct CollectorSupervisor;
Expand Down Expand Up @@ -48,7 +49,7 @@ impl CollectorRefs {
self.collectors.remove(cell)
}
async fn start_all(&mut self, registry: &EbpfEventRegistry, event_actor: &ActorRef<Event>, supervisor: &ActorCell) -> Result<(), ActorProcessingErr> {
for who in [CollectorT::VfsWrite, CollectorT::SysSendmsg, CollectorT::JniCall] {
for who in [CollectorT::VfsWrite, CollectorT::SysSendmsg, CollectorT::JniCall, CollectorT::SysSigquit] {
self.start(who, registry, event_actor, supervisor).await?;
}
Ok(())
Expand All @@ -58,6 +59,7 @@ impl CollectorRefs {
CollectorT::VfsWrite => start_collector(registry.vfs_write_events.clone(), event_actor.clone(), supervisor.clone()).await?,
CollectorT::SysSendmsg => start_collector(registry.sys_sendmsg_events.clone(), event_actor.clone(), supervisor.clone()).await?,
CollectorT::JniCall => start_collector(registry.jni_ref_calls.clone(), event_actor.clone(), supervisor.clone()).await?,
CollectorT::SysSigquit => start_collector(registry.sys_sigquit_events.clone(), event_actor.clone(), supervisor.clone()).await?,
};
self.collectors.insert(actor_ref.get_cell(), who);
Ok(())
Expand Down
6 changes: 6 additions & 0 deletions rust/backend/daemon/src/features/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
mod jni_reference_feature;
mod vfs_write_feature;
mod sys_sendmsg_feature;
mod sys_sigquit_feature;

use std::collections::BTreeSet;
use aya::EbpfError;
use jni_reference_feature::JNIReferencesFeature;
use shared::config::Configuration;
use sys_sendmsg_feature::SysSendmsgFeature;
use sys_sigquit_feature::SysSigquitFeature;
use vfs_write_feature::VfsWriteFeature;

use crate::registry::{EbpfRegistry, OwnedHashMap, RegistryGuard};
Expand All @@ -29,6 +31,7 @@ pub trait Feature {

pub struct Features {
sys_sendmsg_feature: SysSendmsgFeature,
sys_sigquit_feature: SysSigquitFeature,
vfs_write_feature: VfsWriteFeature,
jni_reference_feature: JNIReferencesFeature,
}
Expand All @@ -39,11 +42,13 @@ impl Features {
let sys_sendmsg_feature = SysSendmsgFeature::init(registry);
let vfs_write_feature = VfsWriteFeature::init(registry);
let jni_reference_feature = JNIReferencesFeature::init(registry);
let sys_sigquit_feature = SysSigquitFeature::init(registry);

Self {
sys_sendmsg_feature,
vfs_write_feature,
jni_reference_feature,
sys_sigquit_feature,
}
}

Expand All @@ -56,6 +61,7 @@ impl Features {
self.vfs_write_feature.apply(&config.vfs_write)?;
self.sys_sendmsg_feature.apply(&config.sys_sendmsg)?;
self.jni_reference_feature.apply( &config.jni_references)?;
self.sys_sigquit_feature.apply( &config.sys_sigquit)?;

Ok(())
}
Expand Down
77 changes: 77 additions & 0 deletions rust/backend/daemon/src/features/sys_sigquit_feature.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// SPDX-FileCopyrightText: 2024 Tom Weisshuhn <[email protected]>
//
// SPDX-License-Identifier: MIT

use aya::EbpfError;
use aya::programs::trace_point::TracePointLink;
use aya::programs::TracePoint;
use shared::config::SysSigquitConfig;
use crate::features::{update_pids, Feature};
use crate::registry::{EbpfRegistry, OwnedHashMap, RegistryGuard};

pub struct SysSigquitFeature {
sys_enter_sigquit: RegistryGuard<TracePoint>,
sys_enter_sigquit_link: Option<TracePointLink>,
trace_sigquit_pids: RegistryGuard<OwnedHashMap<u32, u64>>,
}

impl SysSigquitFeature {
fn create(registry: &EbpfRegistry) -> Self {
Self {
sys_enter_sigquit: registry.program.sys_sigquit.take(),
sys_enter_sigquit_link: None,
trace_sigquit_pids: registry.config.sys_sigquit_pids.take(),
}
}

fn attach(&mut self) -> Result<(), EbpfError> {
if self.sys_enter_sigquit_link.is_none() {
let link_id = self.sys_enter_sigquit.attach("syscalls","sys_enter_sigquit")?;
self.sys_enter_sigquit_link = Some(self.sys_enter_sigquit.take_link(link_id)?);
}

Ok(())
}

fn detach(&mut self) {
// the TrakePointLinks will be automatically detached when the reference is dropped
let _ = self.sys_enter_sigquit_link.take();
}

fn update_pids(
&mut self,
pids: &[u32]
) -> Result<(), EbpfError> {

// the general update_pids function for all features works with hashmaps, so the list is converted into a hashmap with keys always being 0
let pid_0_tuples: Vec<(u32, u64)> = pids.iter().map(|pid| (*pid, 0)).collect();
let pids_as_hashmap: std::collections::HashMap<u32, u64> = std::collections::HashMap::from_iter(pid_0_tuples);

update_pids(&pids_as_hashmap, &mut self.trace_sigquit_pids)
}
}

impl Feature for SysSigquitFeature {
type Config = SysSigquitConfig;
fn init(registry: &EbpfRegistry) -> Self {
SysSigquitFeature::create(registry)
}

fn apply(&mut self, config: &Option<Self::Config>) -> Result<(), EbpfError> {
match config {
Some(config) => {
self.attach()?;
self.update_pids(&config.pids)?;
}
None => {
self.detach();
}
}
Ok(())
}
}





Loading
Loading