mirror of
https://github.com/openai/codex.git
synced 2026-04-24 14:45:27 +00:00
add a default dacl to restricted token to enable reading of pipes (#8280)
this fixes sandbox errors (legacy and elevated) for commands that include pipes, which the model often favors.
This commit is contained in:
@@ -4,17 +4,29 @@ use anyhow::Result;
|
||||
use std::ffi::c_void;
|
||||
use windows_sys::Win32::Foundation::CloseHandle;
|
||||
use windows_sys::Win32::Foundation::GetLastError;
|
||||
use windows_sys::Win32::Foundation::LocalFree;
|
||||
use windows_sys::Win32::Foundation::ERROR_SUCCESS;
|
||||
use windows_sys::Win32::Foundation::HANDLE;
|
||||
use windows_sys::Win32::Foundation::HLOCAL;
|
||||
use windows_sys::Win32::Foundation::LUID;
|
||||
use windows_sys::Win32::Security::AdjustTokenPrivileges;
|
||||
use windows_sys::Win32::Security::Authorization::SetEntriesInAclW;
|
||||
use windows_sys::Win32::Security::Authorization::EXPLICIT_ACCESS_W;
|
||||
use windows_sys::Win32::Security::Authorization::GRANT_ACCESS;
|
||||
use windows_sys::Win32::Security::Authorization::TRUSTEE_IS_SID;
|
||||
use windows_sys::Win32::Security::Authorization::TRUSTEE_IS_UNKNOWN;
|
||||
use windows_sys::Win32::Security::Authorization::TRUSTEE_W;
|
||||
use windows_sys::Win32::Security::CopySid;
|
||||
use windows_sys::Win32::Security::CreateRestrictedToken;
|
||||
use windows_sys::Win32::Security::CreateWellKnownSid;
|
||||
use windows_sys::Win32::Security::GetLengthSid;
|
||||
use windows_sys::Win32::Security::GetTokenInformation;
|
||||
use windows_sys::Win32::Security::LookupPrivilegeValueW;
|
||||
use windows_sys::Win32::Security::SetTokenInformation;
|
||||
|
||||
use windows_sys::Win32::Security::TokenDefaultDacl;
|
||||
use windows_sys::Win32::Security::TokenGroups;
|
||||
use windows_sys::Win32::Security::ACL;
|
||||
use windows_sys::Win32::Security::SID_AND_ATTRIBUTES;
|
||||
use windows_sys::Win32::Security::TOKEN_ADJUST_DEFAULT;
|
||||
use windows_sys::Win32::Security::TOKEN_ADJUST_PRIVILEGES;
|
||||
@@ -28,9 +40,71 @@ use windows_sys::Win32::System::Threading::GetCurrentProcess;
|
||||
const DISABLE_MAX_PRIVILEGE: u32 = 0x01;
|
||||
const LUA_TOKEN: u32 = 0x04;
|
||||
const WRITE_RESTRICTED: u32 = 0x08;
|
||||
const GENERIC_ALL: u32 = 0x1000_0000;
|
||||
const WIN_WORLD_SID: i32 = 1;
|
||||
const SE_GROUP_LOGON_ID: u32 = 0xC0000000;
|
||||
|
||||
#[repr(C)]
|
||||
struct TokenDefaultDaclInfo {
|
||||
default_dacl: *mut ACL,
|
||||
}
|
||||
|
||||
/// Sets a permissive default DACL so sandboxed processes can create pipes/IPC objects
|
||||
/// without hitting ACCESS_DENIED when PowerShell builds pipelines.
|
||||
unsafe fn set_default_dacl(h_token: HANDLE, sids: &[*mut c_void]) -> Result<()> {
|
||||
if sids.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
let entries: Vec<EXPLICIT_ACCESS_W> = sids
|
||||
.iter()
|
||||
.map(|sid| EXPLICIT_ACCESS_W {
|
||||
grfAccessPermissions: GENERIC_ALL,
|
||||
grfAccessMode: GRANT_ACCESS,
|
||||
grfInheritance: 0,
|
||||
Trustee: TRUSTEE_W {
|
||||
pMultipleTrustee: std::ptr::null_mut(),
|
||||
MultipleTrusteeOperation: 0,
|
||||
TrusteeForm: TRUSTEE_IS_SID,
|
||||
TrusteeType: TRUSTEE_IS_UNKNOWN,
|
||||
ptstrName: *sid as *mut u16,
|
||||
},
|
||||
})
|
||||
.collect();
|
||||
let mut p_new_dacl: *mut ACL = std::ptr::null_mut();
|
||||
let res = SetEntriesInAclW(
|
||||
entries.len() as u32,
|
||||
entries.as_ptr(),
|
||||
std::ptr::null_mut(),
|
||||
&mut p_new_dacl,
|
||||
);
|
||||
if res != ERROR_SUCCESS {
|
||||
return Err(anyhow!("SetEntriesInAclW failed: {}", res));
|
||||
}
|
||||
let mut info = TokenDefaultDaclInfo {
|
||||
default_dacl: p_new_dacl,
|
||||
};
|
||||
let ok = SetTokenInformation(
|
||||
h_token,
|
||||
TokenDefaultDacl,
|
||||
&mut info as *mut _ as *mut c_void,
|
||||
std::mem::size_of::<TokenDefaultDaclInfo>() as u32,
|
||||
);
|
||||
if ok == 0 {
|
||||
let err = GetLastError();
|
||||
if !p_new_dacl.is_null() {
|
||||
LocalFree(p_new_dacl as HLOCAL);
|
||||
}
|
||||
return Err(anyhow!(
|
||||
"SetTokenInformation(TokenDefaultDacl) failed: {}",
|
||||
err
|
||||
));
|
||||
}
|
||||
if !p_new_dacl.is_null() {
|
||||
LocalFree(p_new_dacl as HLOCAL);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub unsafe fn world_sid() -> Result<Vec<u8>> {
|
||||
let mut size: u32 = 0;
|
||||
CreateWellKnownSid(
|
||||
@@ -267,6 +341,7 @@ pub unsafe fn create_workspace_write_token_with_cap_from(
|
||||
if ok == 0 {
|
||||
return Err(anyhow!("CreateRestrictedToken failed: {}", GetLastError()));
|
||||
}
|
||||
set_default_dacl(new_token, &[psid_logon, psid_everyone, psid_capability])?;
|
||||
enable_single_privilege(new_token, "SeChangeNotifyPrivilege")?;
|
||||
Ok((new_token, psid_capability))
|
||||
}
|
||||
@@ -305,6 +380,7 @@ pub unsafe fn create_readonly_token_with_cap_from(
|
||||
if ok == 0 {
|
||||
return Err(anyhow!("CreateRestrictedToken failed: {}", GetLastError()));
|
||||
}
|
||||
set_default_dacl(new_token, &[psid_logon, psid_everyone, psid_capability])?;
|
||||
enable_single_privilege(new_token, "SeChangeNotifyPrivilege")?;
|
||||
Ok((new_token, psid_capability))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user