fix(ipc): scope active-user IPC routing to root CLI main requests (#15058)

* fix(ipc): scope active-user IPC routing to root CLI main requests

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(ipc): cmdline, comments fails close

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(ipc): cmdline, better check

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(ipc): cmdline, try active uid when no --server processes

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(ipc): cmdline, select active uid

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(ipc): remove unused import

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
fufesou
2026-05-18 16:32:46 +08:00
committed by GitHub
parent 377547fa11
commit bc2c36215d
5 changed files with 317 additions and 30 deletions

View File

@@ -607,27 +607,30 @@ pub(crate) fn log_rejected_windows_ipc_connection(
peer_session_id: Option<u32>,
expected_session_id: Option<u32>,
peer_is_system: Option<bool>,
peer_is_elevated: Option<bool>,
) {
static LOG_THROTTLE: OnceLock<Mutex<UnauthorizedIpcLogThrottle>> = OnceLock::new();
throttled_unauthorized_ipc_log(&LOG_THROTTLE, |suppressed| {
if suppressed > 0 {
log::warn!(
"Rejected unauthorized connection on ipc channel: postfix={}, peer_pid={:?}, peer_session_id={:?}, expected_session_id={:?}, peer_is_system={:?} (suppressed {} similar events)",
"Rejected unauthorized connection on ipc channel: postfix={}, peer_pid={:?}, peer_session_id={:?}, expected_session_id={:?}, peer_is_system={:?}, peer_is_elevated={:?} (suppressed {} similar events)",
postfix,
peer_pid,
peer_session_id,
expected_session_id,
peer_is_system,
peer_is_elevated,
suppressed
);
} else {
log::warn!(
"Rejected unauthorized connection on ipc channel: postfix={}, peer_pid={:?}, peer_session_id={:?}, expected_session_id={:?}, peer_is_system={:?}",
"Rejected unauthorized connection on ipc channel: postfix={}, peer_pid={:?}, peer_session_id={:?}, expected_session_id={:?}, peer_is_system={:?}, peer_is_elevated={:?}",
postfix,
peer_pid,
peer_session_id,
expected_session_id,
peer_is_system
peer_is_system,
peer_is_elevated
);
}
});
@@ -655,8 +658,14 @@ pub(crate) fn authorize_service_scoped_ipc_connection(stream: &Connection, postf
#[cfg(windows)]
pub(crate) fn authorize_windows_main_ipc_connection(stream: &Connection, postfix: &str) -> bool {
let (authorized, peer_pid, peer_session_id, server_session_id, peer_is_system) =
stream.server_authorization_status();
let (
authorized,
peer_pid,
peer_session_id,
server_session_id,
peer_is_system,
peer_is_elevated,
) = stream.server_authorization_status();
if !authorized {
log_rejected_windows_ipc_connection(
postfix,
@@ -664,6 +673,7 @@ pub(crate) fn authorize_windows_main_ipc_connection(stream: &Connection, postfix
peer_session_id,
server_session_id,
peer_is_system,
peer_is_elevated,
);
return false;
}
@@ -776,7 +786,14 @@ impl ConnectionTmpl<parity_tokio_ipc::Connection> {
fn server_authorization_status(
&self,
) -> (bool, Option<u32>, Option<u32>, Option<u32>, Option<bool>) {
) -> (
bool,
Option<u32>,
Option<u32>,
Option<u32>,
Option<bool>,
Option<bool>,
) {
let peer_pid = self.peer_pid();
let server_session_id = crate::platform::windows::get_current_process_session_id();
let peer_session_id =
@@ -786,20 +803,34 @@ impl ConnectionTmpl<parity_tokio_ipc::Connection> {
let peer_is_system = peer_is_system_result
.as_ref()
.and_then(|r| r.as_ref().ok().copied());
if server_session_id.is_none() && !peer_is_system.unwrap_or(false) {
// When the server session id cannot be determined, the session-id allow-path is
// disabled and only SYSTEM peers can be authorized.
log::debug!(
"IPC authorization: server session id unavailable; rejecting non-SYSTEM peer, peer_pid={:?}, peer_session_id={:?}",
peer_pid,
peer_session_id
);
}
let authorized = is_allowed_windows_session_scoped_peer(
let session_authorized = is_allowed_windows_session_scoped_peer(
peer_is_system.unwrap_or(false),
peer_session_id,
server_session_id,
);
let peer_is_elevated_result = if session_authorized {
None
} else {
peer_pid.map(|pid| crate::platform::windows::is_elevated(Some(pid)))
};
let peer_is_elevated = peer_is_elevated_result
.as_ref()
.and_then(|r| r.as_ref().ok().copied());
if server_session_id.is_none()
&& !peer_is_system.unwrap_or(false)
&& !peer_is_elevated.unwrap_or(false)
{
// When the server session id cannot be determined, the session-id allow-path is
// disabled and only privileged peers can be authorized.
log::debug!(
"IPC authorization: server session id unavailable; rejecting non-privileged peer, peer_pid={:?}, peer_session_id={:?}",
peer_pid,
peer_session_id
);
}
// Main IPC trusts same-session peers, LocalSystem, and elevated administrators.
// Service-scoped IPC channels keep their own stricter authorization paths.
let authorized = session_authorized || peer_is_elevated.unwrap_or(false);
if !authorized {
if let (Some(pid), Some(Err(err))) = (peer_pid, peer_is_system_result.as_ref()) {
log::debug!(
@@ -808,6 +839,13 @@ impl ConnectionTmpl<parity_tokio_ipc::Connection> {
err
);
}
if let (Some(pid), Some(Err(err))) = (peer_pid, peer_is_elevated_result.as_ref()) {
log::debug!(
"Failed to determine whether peer process is elevated, pid={}, err={}",
pid,
err
);
}
}
(
authorized,
@@ -815,6 +853,7 @@ impl ConnectionTmpl<parity_tokio_ipc::Connection> {
peer_session_id,
server_session_id,
peer_is_system,
peer_is_elevated,
)
}