From cc734a135c0eee7d9817035d0764eec918ef19e3 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Sat, 3 May 2025 13:03:48 +0200 Subject: [PATCH] config: add comm client criteria --- jay-config/src/_private.rs | 1 + jay-config/src/_private/client.rs | 2 ++ jay-config/src/client.rs | 4 ++++ src/config/handler.rs | 1 + src/criteria/clm.rs | 9 ++++++++- src/criteria/clm/clm_matchers/clmm_string.rs | 12 ++++++++++++ toml-config/src/config.rs | 2 ++ toml-config/src/config/parsers/client_match.rs | 14 +++++++++++++- toml-config/src/rules.rs | 2 ++ toml-spec/spec/spec.generated.json | 8 ++++++++ toml-spec/spec/spec.generated.md | 12 ++++++++++++ toml-spec/spec/spec.yaml | 8 ++++++++ 12 files changed, 73 insertions(+), 2 deletions(-) diff --git a/jay-config/src/_private.rs b/jay-config/src/_private.rs index ba22f5a8..7229991c 100644 --- a/jay-config/src/_private.rs +++ b/jay-config/src/_private.rs @@ -92,4 +92,5 @@ pub enum ClientCriterionStringField { SandboxEngine, SandboxAppId, SandboxInstanceId, + Comm, } diff --git a/jay-config/src/_private/client.rs b/jay-config/src/_private/client.rs index 93993232..559bec40 100644 --- a/jay-config/src/_private/client.rs +++ b/jay-config/src/_private/client.rs @@ -1545,6 +1545,8 @@ impl ConfigClient { ClientCriterion::Uid(p) => ClientCriterionIpc::Uid(p), ClientCriterion::Pid(p) => ClientCriterionIpc::Pid(p), ClientCriterion::IsXwayland => ClientCriterionIpc::IsXwayland, + ClientCriterion::Comm(t) => string!(t, Comm, false), + ClientCriterion::CommRegex(t) => string!(t, Comm, true), }; let res = self.send_with_response(&ClientMessage::CreateClientMatcher { criterion }); get_response!( diff --git a/jay-config/src/client.rs b/jay-config/src/client.rs index 9fed07ea..6dc7487b 100644 --- a/jay-config/src/client.rs +++ b/jay-config/src/client.rs @@ -83,6 +83,10 @@ pub enum ClientCriterion<'a> { Pid(i32), /// Matches if the client is Xwayland. IsXwayland, + /// Matches the `/proc/pid/comm` of the client verbatim. + Comm(&'a str), + /// Matches the `/proc/pid/comm` of the client with a regular expression. + CommRegex(&'a str), } impl ClientCriterion<'_> { diff --git a/src/config/handler.rs b/src/config/handler.rs index b329947e..00a9fecd 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -1882,6 +1882,7 @@ impl ConfigProxyHandler { ClientCriterionStringField::SandboxInstanceId => { mgr.sandbox_instance_id(needle) } + ClientCriterionStringField::Comm => mgr.comm(needle), } } ClientCriterionIpc::Sandboxed => mgr.sandboxed(), diff --git a/src/criteria/clm.rs b/src/criteria/clm.rs index 243ae514..802d26f8 100644 --- a/src/criteria/clm.rs +++ b/src/criteria/clm.rs @@ -11,7 +11,8 @@ use { clmm_pid::ClmMatchPid, clmm_sandboxed::ClmMatchSandboxed, clmm_string::{ - ClmMatchSandboxAppId, ClmMatchSandboxEngine, ClmMatchSandboxInstanceId, + ClmMatchComm, ClmMatchSandboxAppId, ClmMatchSandboxEngine, + ClmMatchSandboxInstanceId, }, clmm_uid::ClmMatchUid, }, @@ -58,6 +59,7 @@ pub struct RootMatchers { sandbox_instance_id: ClmRootMatcherMap, uid: ClmRootMatcherMap, pid: ClmRootMatcherMap, + comm: ClmRootMatcherMap, } pub async fn handle_cl_changes(state: Rc) { @@ -160,6 +162,7 @@ impl ClMatcherManager { unconditional!(sandbox_engine); unconditional!(uid); unconditional!(pid); + unconditional!(comm); fixed!(sandboxed); fixed!(is_xwayland); self.constant[true].handle(data); @@ -193,6 +196,10 @@ impl ClMatcherManager { pub fn is_xwayland(&self) -> Rc { self.is_xwayland[true].clone() } + + pub fn comm(&self, string: CritLiteralOrRegex) -> Rc { + self.root(ClmMatchComm::new(string)) + } } impl CritTarget for Rc { diff --git a/src/criteria/clm/clm_matchers/clmm_string.rs b/src/criteria/clm/clm_matchers/clmm_string.rs index 9e4c58c7..c0369b32 100644 --- a/src/criteria/clm/clm_matchers/clmm_string.rs +++ b/src/criteria/clm/clm_matchers/clmm_string.rs @@ -15,8 +15,10 @@ pub type ClmMatchString = CritMatchString, T>; pub type ClmMatchSandboxEngine = ClmMatchString>; pub type ClmMatchSandboxAppId = ClmMatchString>; pub type ClmMatchSandboxInstanceId = ClmMatchString>; +pub type ClmMatchComm = ClmMatchString; pub struct AcceptorMetadataAccess(PhantomData); +pub struct CommAccess; trait SandboxField: Sized + 'static { fn field(meta: &AcceptorMetadata) -> &Option; @@ -77,3 +79,13 @@ impl SandboxField for SandboxInstanceIdField { &roots.sandbox_instance_id } } + +impl StringAccess> for CommAccess { + fn with_string(data: &Rc, f: impl FnOnce(&str) -> bool) -> bool { + f(&data.pid_info.comm) + } + + fn nodes(roots: &RootMatchers) -> &ClmRootMatcherMap> { + &roots.comm + } +} diff --git a/toml-config/src/config.rs b/toml-config/src/config.rs index 207adfc9..8f51e220 100644 --- a/toml-config/src/config.rs +++ b/toml-config/src/config.rs @@ -235,6 +235,8 @@ pub struct ClientMatch { pub uid: Option, pub pid: Option, pub is_xwayland: Option, + pub comm: Option, + pub comm_regex: Option, } #[derive(Debug, Clone)] diff --git a/toml-config/src/config/parsers/client_match.rs b/toml-config/src/config/parsers/client_match.rs index 31be8bbb..852cd9d2 100644 --- a/toml-config/src/config/parsers/client_match.rs +++ b/toml-config/src/config/parsers/client_match.rs @@ -49,7 +49,15 @@ impl Parser for ClientMatchParser<'_> { sandbox_app_id, sandbox_app_id_regex, ), - (sandbox_instance_id, sandbox_instance_id_regex, uid, pid, is_xwayland), + ( + sandbox_instance_id, + sandbox_instance_id_regex, + uid, + pid, + is_xwayland, + comm, + comm_regex, + ), ) = ext.extract(( ( opt(str("name")), @@ -69,6 +77,8 @@ impl Parser for ClientMatchParser<'_> { opt(s32("uid")), opt(s32("pid")), opt(bol("is-xwayland")), + opt(str("comm")), + opt(str("comm-regex")), ), ))?; let mut not = None; @@ -112,6 +122,8 @@ impl Parser for ClientMatchParser<'_> { uid: uid.despan(), pid: pid.despan(), is_xwayland: is_xwayland.despan(), + comm: comm.despan_into(), + comm_regex: comm_regex.despan_into(), }) } } diff --git a/toml-config/src/rules.rs b/toml-config/src/rules.rs index 9f482fdb..c54550ec 100644 --- a/toml-config/src/rules.rs +++ b/toml-config/src/rules.rs @@ -120,6 +120,8 @@ impl Rule for ClientRule { value_ref!(SandboxAppIdRegex, sandbox_app_id_regex); value_ref!(SandboxInstanceId, sandbox_instance_id); value_ref!(SandboxInstanceIdRegex, sandbox_instance_id_regex); + value_ref!(Comm, comm); + value_ref!(CommRegex, comm_regex); value!(Uid, uid); value!(Pid, pid); bool!(Sandboxed, sandboxed); diff --git a/toml-spec/spec/spec.generated.json b/toml-spec/spec/spec.generated.json index 3ec70136..92dcdaa8 100644 --- a/toml-spec/spec/spec.generated.json +++ b/toml-spec/spec/spec.generated.json @@ -571,6 +571,14 @@ "is-xwayland": { "type": "boolean", "description": "Matches if the client is/isn't Xwayland." + }, + "comm": { + "type": "string", + "description": "Matches the `/proc/pid/comm` of the client verbatim." + }, + "comm-regex": { + "type": "string", + "description": "Matches the `/proc/pid/comm` of the client with a regular expression." } }, "required": [] diff --git a/toml-spec/spec/spec.generated.md b/toml-spec/spec/spec.generated.md index a20505dd..c7286091 100644 --- a/toml-spec/spec/spec.generated.md +++ b/toml-spec/spec/spec.generated.md @@ -893,6 +893,18 @@ The table has the following fields: The value of this field should be a boolean. +- `comm` (optional): + + Matches the `/proc/pid/comm` of the client verbatim. + + The value of this field should be a string. + +- `comm-regex` (optional): + + Matches the `/proc/pid/comm` of the client with a regular expression. + + The value of this field should be a string. + ### `ClientMatchExactly` diff --git a/toml-spec/spec/spec.yaml b/toml-spec/spec/spec.yaml index 1c93dd78..f124139b 100644 --- a/toml-spec/spec/spec.yaml +++ b/toml-spec/spec/spec.yaml @@ -3251,6 +3251,14 @@ ClientMatch: kind: boolean required: false description: Matches if the client is/isn't Xwayland. + comm: + kind: string + required: false + description: Matches the `/proc/pid/comm` of the client verbatim. + comm-regex: + kind: string + required: false + description: Matches the `/proc/pid/comm` of the client with a regular expression. ClientMatchExactly: