修复新建项目目录权限收紧兜底
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 5m13s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Successful in 5m14s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 5m31s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m50s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Successful in 3m51s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m22s
Project CI / Repository checks (pull_request) Successful in 3m40s
Project CI / Frontend tests (pull_request) Successful in 5m57s
Project CI / Backend tests (pull_request) Successful in 9m14s
Project CI / AI game creator shell web tests (pull_request) Successful in 3m33s
Project CI / Native shell tests (pull_request) Successful in 7m53s

新建目录优先使用当前进程初始化 owner 与私有 DACL

仅在受控 managed 路径本地加固失败时执行一次 UAC 修复

统一目录创建分支并复核最终 Windows ACL
This commit is contained in:
2026-09-15 00:26:28 +08:00
parent 405ad7808c
commit f8253a0272
@@ -1319,12 +1319,10 @@ pub(crate) fn ensure_game_creator_private_directory_tree(
#[cfg(all(windows, test))]
initialize_windows_game_creator_directory_owner_for_current_user(&directory)?;
#[cfg(windows)]
// This invocation created the directory, so initialize its
// owner/DACL in-process. Marker-based managed-path detection
// must not route a newly-created descendant into UAC.
secure_windows_game_creator_path_for_current_user_with_owner_policy(
&directory, true, true, true,
)?;
// This invocation created the directory: initialize it in
// process first, with a narrowly-scoped managed-path fallback
// only if Windows rejects that local ACL update.
harden_new_game_creator_private_path(&directory, true, label)?;
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
@@ -1363,11 +1361,7 @@ pub(crate) fn ensure_game_creator_private_directory_tree(
fs::create_dir(&directory).map_err(|retry_error| {
format!("创建 {label} 失败:{}: {retry_error}", directory.display())
})?;
// The retry also created this directory in the current
// process; keep it on the local hardening path.
secure_windows_game_creator_path_for_current_user_with_owner_policy(
&directory, true, true, true,
)?;
harden_new_game_creator_private_path(&directory, true, label)?;
}
Err(error) => {
return Err(format!(
@@ -1432,15 +1426,34 @@ pub(crate) fn harden_new_game_creator_private_path(
path.display()
));
}
// This invocation created the object, so its owner is the current
// user. Tighten the inherited descriptor in-process; UAC repair is
// reserved for existing, externally-owned objects.
secure_windows_game_creator_path_for_current_user_with_owner_policy(
path,
is_directory,
true,
true,
)?;
// This invocation created the object, so local hardening is always
// the first path. Some Windows configurations can nevertheless
// reject the descriptor update (for example when an inherited ACL is
// protected by the parent). Only a managed path may use the existing
// one-shot repair in that exceptional case; ordinary new projects do
// not prompt for UAC.
if let Err(local_error) =
secure_windows_game_creator_path_for_current_user_with_owner_policy(
path,
is_directory,
true,
true,
)
{
if !game_creator_private_path_allows_auto_elevation(path)
|| !windows_acl_error_may_need_elevation(&local_error)
{
return Err(local_error);
}
secure_windows_game_creator_path_for_current_user_with_auto_elevation(
path,
is_directory,
true,
)
.map_err(|repair_error| {
format!("{local_error};新建对象的受控 ACL 修复未完成:{repair_error}")
})?;
}
}
#[cfg(unix)]
{