mirror of
https://github.com/bitwarden/browser
synced 2026-02-24 08:33:29 +00:00
Fix biometric authentication in sandboxed environments (Flatpak, Snap, etc.) (#18625)
Biometric authentication was failing in Flatpak with the error "Unix process subject does not have uid set". This occurred because polkit could not validate the sandboxed PID against the host PID namespace. Use polkit's system-bus-name subject type instead of unix-process. This allows polkit to query D-Bus for the connection owner's host PID and credentials, bypassing the PID namespace issue. Includes fallback to unix-process for edge cases where D-Bus unique name is unavailable.
This commit is contained in:
@@ -21,7 +21,32 @@ impl super::BiometricTrait for Biometric {
|
||||
async fn prompt(_hwnd: Vec<u8>, _message: String) -> Result<bool> {
|
||||
let connection = Connection::system().await?;
|
||||
let proxy = AuthorityProxy::new(&connection).await?;
|
||||
let subject = Subject::new_for_owner(std::process::id(), None, None)?;
|
||||
|
||||
// Use system-bus-name instead of unix-process to avoid PID namespace issues in
|
||||
// sandboxed environments (e.g., Flatpak). When using unix-process with a PID from
|
||||
// inside the sandbox, polkit cannot validate it against the host PID namespace.
|
||||
//
|
||||
// By using system-bus-name, polkit queries D-Bus for the connection's credentials,
|
||||
// which includes the correct host PID and UID, avoiding namespace mismatches.
|
||||
//
|
||||
// If D-Bus unique name is not available, fall back to the traditional unix-process
|
||||
// approach for compatibility with non-sandboxed environments.
|
||||
let subject = if let Some(bus_name) = connection.unique_name() {
|
||||
use zbus::zvariant::{OwnedValue, Str};
|
||||
let mut subject_details = std::collections::HashMap::new();
|
||||
subject_details.insert(
|
||||
"name".to_string(),
|
||||
OwnedValue::from(Str::from(bus_name.as_str())),
|
||||
);
|
||||
Subject {
|
||||
subject_kind: "system-bus-name".to_string(),
|
||||
subject_details,
|
||||
}
|
||||
} else {
|
||||
// Fallback: use unix-process with PID (may not work in sandboxed environments)
|
||||
Subject::new_for_owner(std::process::id(), None, None)?
|
||||
};
|
||||
|
||||
let details = std::collections::HashMap::new();
|
||||
let result = proxy
|
||||
.check_authorization(
|
||||
|
||||
@@ -96,7 +96,32 @@ async fn polkit_authenticate_bitwarden_policy() -> Result<bool> {
|
||||
|
||||
let connection = Connection::system().await?;
|
||||
let proxy = AuthorityProxy::new(&connection).await?;
|
||||
let subject = Subject::new_for_owner(std::process::id(), None, None)?;
|
||||
|
||||
// Use system-bus-name instead of unix-process to avoid PID namespace issues in
|
||||
// sandboxed environments (e.g., Flatpak). When using unix-process with a PID from
|
||||
// inside the sandbox, polkit cannot validate it against the host PID namespace.
|
||||
//
|
||||
// By using system-bus-name, polkit queries D-Bus for the connection's credentials,
|
||||
// which includes the correct host PID and UID, avoiding namespace mismatches.
|
||||
//
|
||||
// If D-Bus unique name is not available, fall back to the traditional unix-process
|
||||
// approach for compatibility with non-sandboxed environments.
|
||||
let subject = if let Some(bus_name) = connection.unique_name() {
|
||||
use zbus::zvariant::{OwnedValue, Str};
|
||||
let mut subject_details = std::collections::HashMap::new();
|
||||
subject_details.insert(
|
||||
"name".to_string(),
|
||||
OwnedValue::from(Str::from(bus_name.as_str())),
|
||||
);
|
||||
Subject {
|
||||
subject_kind: "system-bus-name".to_string(),
|
||||
subject_details,
|
||||
}
|
||||
} else {
|
||||
// Fallback: use unix-process with PID (may not work in sandboxed environments)
|
||||
Subject::new_for_owner(std::process::id(), None, None)?
|
||||
};
|
||||
|
||||
let details = std::collections::HashMap::new();
|
||||
let authorization_result = proxy
|
||||
.check_authorization(
|
||||
|
||||
Reference in New Issue
Block a user