低风险: 多实例运行时令牌文件竞态条件 (cap_portal.rs) #4

Closed
opened 2026-06-04 20:58:33 +08:00 by dailz · 1 comment
Owner

位置

src/cap_portal.rs:255-260

严重性

🟢

问题描述

load_restore_tokensave_restore_token 之间没有文件锁保护。当同一用户同时运行多个 wl-webrtc 实例时:

  1. 两个实例可能使用同一个恢复令牌尝试恢复会话
  2. 两个实例先后写入新令牌,后写入的覆盖前者

虽然同时运行多个屏幕捕获实例的场景较少见,但按 Portal 的 ExplicitlyRevoked 持久化模式设计,每个会话应有独立的恢复令牌。

建议处理

该风险可接受,建议添加注释说明即可:

fn load_restore_token() -> Option<String> {
    let path = token_path();
    // Read is inherently racy without locking, but the consequence is limited
    // to a potential re-authorization prompt on the next run.
    let token = std::fs::read_to_string(&path).ok()?;
    let trimmed = token.trim().to_string();
    if trimmed.is_empty() { None } else { Some(trimmed) }
}
## 位置 `src/cap_portal.rs:255-260` ## 严重性 🟢 低 ## 问题描述 `load_restore_token` 和 `save_restore_token` 之间没有文件锁保护。当同一用户同时运行多个 wl-webrtc 实例时: 1. 两个实例可能使用同一个恢复令牌尝试恢复会话 2. 两个实例先后写入新令牌,后写入的覆盖前者 虽然同时运行多个屏幕捕获实例的场景较少见,但按 Portal 的 `ExplicitlyRevoked` 持久化模式设计,每个会话应有独立的恢复令牌。 ## 建议处理 该风险可接受,建议添加注释说明即可: ```rust fn load_restore_token() -> Option<String> { let path = token_path(); // Read is inherently racy without locking, but the consequence is limited // to a potential re-authorization prompt on the next run. let token = std::fs::read_to_string(&path).ok()?; let trimmed = token.trim().to_string(); if trimmed.is_empty() { None } else { Some(trimmed) } } ```
Author
Owner

经审核,单实例场景下 load_restore_token 和 save_restore_token 在 setup_portal 中是串行调用(L192 读 → L227 写),不存在竞态条件。此 issue 仅在多实例同时运行时成立,当前不考虑该场景,故关闭。

经审核,单实例场景下 load_restore_token 和 save_restore_token 在 setup_portal 中是串行调用(L192 读 → L227 写),不存在竞态条件。此 issue 仅在多实例同时运行时成立,当前不考虑该场景,故关闭。
dailz closed this issue 2026-06-06 11:50:34 +08:00
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dailz/wl-webrtc#4