Repository navigation
Enable the Windows CEF sandbox and update x64 to CEF 6613 #775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
summeroff
wants to merge
20
commits into
streamlabs
Choose a base branch
from
security/windows-cef-sandbox
base: streamlabs
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,233
−39
Open
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
a936601
Package and export the Windows CEF sandbox
summeroff 466602e
Apply CMake formatting
summeroff 5eebdb2
Skip oversized CEF PDB in symbol upload
summeroff 603f8fa
Make CEF sandbox gating generator independent
summeroff 98cc448
Update obs-browser sandbox hardening
summeroff 6ea2a7c
Fix obs-browser submodule revision
summeroff f6141a5
Update obs-browser CI hardening
summeroff 488e9eb
Update Windows x64 to CEF 6613
summeroff 22652cc
Publish stripped CEF symbols to the symbol server
summeroff 831c294
Add compatible CEF PDB relink helper
summeroff 343b64d
Harden CEF relink output validation
summeroff 181e6ae
Align workflow metadata with CEF 6613
summeroff 5cc79ea
Address CEF sandbox review feedback
summeroff 58a66c5
Update obs-browser submodule to ABI logging fix
summeroff 526478a
cmake: refresh CEF discovery when selected dependency changes
summeroff b0ffe74
cmake: align CEF sandbox exports with package layout
summeroff 2d6a813
Guard CEF PDB output aliases and retain explicit cache overrides
summeroff 7156c0a
cmake: restore libobs package prefix after dependencies
summeroff e12b0da
deps: pin Windows x64 CEF 6613 revision 3
summeroff fc6d947
ci: select CEF 6613 revision 3 in legacy Windows jobs
summeroff File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,236 @@ | ||
| #Requires -Version 7.2 | ||
|
|
||
| # Chromium links libcef with lld-link. Although that linker advertises | ||
| # /PDBSTRIPPED in its help output, Chromium 128's bundled version rejects the | ||
| # option as unimplemented. Produce the equivalent matching public PDB with the | ||
| # Windows SDK's supported post-link tool instead. | ||
|
|
||
| [CmdletBinding()] | ||
| param( | ||
| [Parameter(Mandatory)] | ||
| [string] $CefOutDirectory, | ||
|
|
||
| [string] $PdbCopyPath, | ||
|
|
||
| [string] $LlvmPdbUtilPath, | ||
|
|
||
| [string] $OutputPath, | ||
|
|
||
| [ValidateRange(1, [long]::MaxValue)] | ||
| [long] $MaximumBytes = 2147483647, | ||
|
|
||
| [switch] $ReplaceExisting | ||
| ) | ||
|
|
||
| Set-StrictMode -Version Latest | ||
| $ErrorActionPreference = 'Stop' | ||
|
|
||
| function Resolve-Executable { | ||
| param( | ||
| [Parameter(Mandatory)] | ||
| [string] $Name, | ||
|
|
||
| [string] $RequestedPath, | ||
|
|
||
| [string[]] $Candidates = @() | ||
| ) | ||
|
|
||
| if ($RequestedPath) { | ||
| return (Resolve-Path -LiteralPath $RequestedPath).Path | ||
| } | ||
|
|
||
| $command = Get-Command $Name -ErrorAction SilentlyContinue | ||
| if ($command) { | ||
| return $command.Source | ||
| } | ||
|
|
||
| foreach ($candidate in $Candidates) { | ||
| if ($candidate -and (Test-Path -LiteralPath $candidate -PathType Leaf)) { | ||
| return (Resolve-Path -LiteralPath $candidate).Path | ||
| } | ||
| } | ||
|
|
||
| throw "Could not find $Name. Pass its path explicitly." | ||
| } | ||
|
|
||
| function Get-PdbIdentity { | ||
| param( | ||
| [Parameter(Mandatory)] | ||
| [string] $PdbPath, | ||
|
|
||
| [Parameter(Mandatory)] | ||
| [string] $PdbUtil | ||
| ) | ||
|
|
||
| $summary = @(& $PdbUtil dump -summary $PdbPath 2>&1) | ||
| if ($LASTEXITCODE -ne 0) { | ||
| throw "llvm-pdbutil could not inspect '$PdbPath':`n$($summary -join "`n")" | ||
| } | ||
|
|
||
| $summaryText = $summary -join "`n" | ||
| $guid = [regex]::Match($summaryText, '(?m)^\s*GUID:\s*(\{[^}]+\})\s*$') | ||
| $age = [regex]::Match($summaryText, '(?m)^\s*Age:\s*(\d+)\s*$') | ||
| $stripped = [regex]::Match($summaryText, '(?m)^\s*Is stripped:\s*(true|false)\s*$') | ||
| if (-not $guid.Success -or -not $age.Success -or -not $stripped.Success) { | ||
| throw "llvm-pdbutil returned an unrecognized summary for '$PdbPath'." | ||
| } | ||
|
|
||
| return [pscustomobject]@{ | ||
| Guid = $guid.Groups[1].Value.ToUpperInvariant() | ||
| Age = [int] $age.Groups[1].Value | ||
| IsStripped = $stripped.Groups[1].Value -eq 'true' | ||
| } | ||
| } | ||
|
|
||
| function Resolve-PhysicalPath { | ||
| param( | ||
| [Parameter(Mandatory)] | ||
| [string] $Path | ||
| ) | ||
|
|
||
| $fullPath = [System.IO.Path]::GetFullPath($Path) | ||
| $root = [System.IO.Path]::GetPathRoot($fullPath) | ||
| $current = $root | ||
| $components = $fullPath.Substring($root.Length).TrimStart('\', '/') -split '[\\/]+' | ||
| for ($index = 0; $index -lt $components.Count; $index++) { | ||
| $candidate = Join-Path $current $components[$index] | ||
| try { | ||
| $item = Get-Item -LiteralPath $candidate -Force -ErrorAction Stop | ||
| } catch [System.Management.Automation.ItemNotFoundException] { | ||
| if ($index -ne $components.Count - 1) { | ||
| throw "Could not inspect path component: $candidate" | ||
| } | ||
| if ([System.IO.FileInfo]::new($candidate).LinkTarget) { | ||
| throw "The public PDB output is a dangling link: $candidate" | ||
| } | ||
| return [System.IO.Path]::GetFullPath($candidate) | ||
| } | ||
| if (($item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) -ne 0) { | ||
| $target = $item.ResolveLinkTarget($true) | ||
| if ($null -eq $target -or -not $target.Exists) { | ||
| throw "Could not resolve reparse point or its target: $candidate" | ||
| } | ||
| $current = $target.FullName | ||
| } else { | ||
| $current = $item.FullName | ||
| } | ||
| } | ||
| return [System.IO.Path]::GetFullPath($current) | ||
| } | ||
|
|
||
| function Assert-SafePublicPdbPath { | ||
| param( | ||
| [Parameter(Mandatory)] | ||
| [string] $CefOut, | ||
|
|
||
| [Parameter(Mandatory)] | ||
| [string] $PrivatePdb, | ||
|
|
||
| [Parameter(Mandatory)] | ||
| [string] $PublicPdb | ||
| ) | ||
|
|
||
| $cefOutPhysical = Resolve-PhysicalPath -Path $CefOut | ||
| $privatePdbPhysical = Resolve-PhysicalPath -Path $PrivatePdb | ||
| $publicPdbPhysical = Resolve-PhysicalPath -Path $PublicPdb | ||
| $comparison = [System.StringComparison]::OrdinalIgnoreCase | ||
| if ($publicPdbPhysical.Equals($privatePdbPhysical, $comparison)) { | ||
| throw 'The public PDB output must not overwrite the private PDB.' | ||
| } | ||
| if (-not $publicPdbPhysical.StartsWith("$($cefOutPhysical.TrimEnd('\', '/'))$([System.IO.Path]::DirectorySeparatorChar)", | ||
| $comparison)) { | ||
| throw "The public PDB output resolves outside the CEF output directory: $publicPdbPhysical" | ||
| } | ||
| } | ||
|
|
||
| $cefOut = (Resolve-Path -LiteralPath $CefOutDirectory).Path | ||
| $cefRoot = (Resolve-Path -LiteralPath (Join-Path $cefOut '..')).Path | ||
| $cefSource = (Resolve-Path -LiteralPath (Join-Path $cefOut '..\..')).Path | ||
| $privatePdb = Join-Path $cefOut 'libcef.dll.pdb' | ||
| if (-not (Test-Path -LiteralPath $privatePdb -PathType Leaf)) { | ||
| throw "The CEF private PDB does not exist: $privatePdb" | ||
| } | ||
|
|
||
| if (-not $OutputPath) { | ||
| $OutputPath = Join-Path $cefOut 'libcef.dll.public.pdb' | ||
| } elseif (-not [System.IO.Path]::IsPathRooted($OutputPath)) { | ||
| $OutputPath = Join-Path $cefOut $OutputPath | ||
| } | ||
| $outputDirectory = Split-Path -Parent $OutputPath | ||
| if (-not (Test-Path -LiteralPath $outputDirectory -PathType Container)) { | ||
| throw "The public PDB output directory does not exist: $outputDirectory" | ||
| } | ||
| $publicPdb = [System.IO.Path]::GetFullPath($OutputPath) | ||
| if ($publicPdb -eq $privatePdb) { | ||
| throw 'The public PDB output must not overwrite the private PDB.' | ||
| } | ||
| $relativeOutput = [System.IO.Path]::GetRelativePath($cefOut, $publicPdb) | ||
| if ( | ||
| [System.IO.Path]::IsPathRooted($relativeOutput) -or | ||
| $relativeOutput -eq '..' -or | ||
| $relativeOutput.StartsWith("..$([System.IO.Path]::DirectorySeparatorChar)") -or | ||
| $relativeOutput.StartsWith("..$([System.IO.Path]::AltDirectorySeparatorChar)") | ||
| ) { | ||
| throw "The public PDB output must remain inside the CEF output directory: $cefOut" | ||
| } | ||
| Assert-SafePublicPdbPath -CefOut $cefOut -PrivatePdb $privatePdb -PublicPdb $publicPdb | ||
| if (Test-Path -LiteralPath $publicPdb) { | ||
| if (-not $ReplaceExisting) { | ||
| throw "The public PDB already exists. Pass -ReplaceExisting to regenerate it: $publicPdb" | ||
| } | ||
| Assert-SafePublicPdbPath -CefOut $cefOut -PrivatePdb $privatePdb -PublicPdb $publicPdb | ||
| Remove-Item -LiteralPath $publicPdb -Force | ||
| } | ||
|
|
||
| $windowsKitsPdbCopy = if (${env:ProgramFiles(x86)}) { | ||
| Join-Path ${env:ProgramFiles(x86)} 'Windows Kits\10\Debuggers\x64\pdbcopy.exe' | ||
| } | ||
| $pdbCopy = Resolve-Executable -Name 'pdbcopy.exe' -RequestedPath $PdbCopyPath -Candidates @($windowsKitsPdbCopy) | ||
| $pdbUtil = Resolve-Executable -Name 'llvm-pdbutil.exe' -RequestedPath $LlvmPdbUtilPath -Candidates @( | ||
| (Join-Path $cefSource 'third_party\llvm-build\Release+Asserts\bin\llvm-pdbutil.exe'), | ||
| (Join-Path $cefRoot 'third_party\llvm-build\Release+Asserts\bin\llvm-pdbutil.exe'), | ||
| (Join-Path $env:ProgramFiles 'LLVM\bin\llvm-pdbutil.exe'), | ||
| (Join-Path $env:ProgramFiles 'Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin\llvm-pdbutil.exe'), | ||
| (Join-Path $env:ProgramFiles 'Microsoft Visual Studio\2022\Professional\VC\Tools\Llvm\x64\bin\llvm-pdbutil.exe'), | ||
| (Join-Path $env:ProgramFiles 'Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\x64\bin\llvm-pdbutil.exe'), | ||
| (Join-Path $env:ProgramFiles 'Microsoft Visual Studio\2022\BuildTools\VC\Tools\Llvm\x64\bin\llvm-pdbutil.exe') | ||
| ) | ||
|
|
||
| Assert-SafePublicPdbPath -CefOut $cefOut -PrivatePdb $privatePdb -PublicPdb $publicPdb | ||
| $pdbCopyOutput = @(& $pdbCopy $privatePdb $publicPdb -p 2>&1) | ||
| if ($LASTEXITCODE -ne 0) { | ||
| throw ( | ||
| "pdbcopy failed. Older Windows SDK versions cannot read PDBs larger than 4 GiB; " + | ||
| "rebuild CEF with symbol_level=1 first.`n$($pdbCopyOutput -join "`n")" | ||
| ) | ||
| } | ||
| if (-not (Test-Path -LiteralPath $publicPdb -PathType Leaf)) { | ||
| throw "pdbcopy did not produce the requested public PDB: $publicPdb" | ||
| } | ||
|
|
||
| $privateIdentity = Get-PdbIdentity -PdbPath $privatePdb -PdbUtil $pdbUtil | ||
| $publicIdentity = Get-PdbIdentity -PdbPath $publicPdb -PdbUtil $pdbUtil | ||
| if ($privateIdentity.Guid -ne $publicIdentity.Guid -or $privateIdentity.Age -ne $publicIdentity.Age) { | ||
| throw 'The public PDB does not have the same GUID and age as the private PDB.' | ||
| } | ||
| if (-not $publicIdentity.IsStripped) { | ||
| throw 'The generated public PDB is not marked as stripped.' | ||
| } | ||
|
|
||
| $publicFile = Get-Item -LiteralPath $publicPdb | ||
| if ($publicFile.Length -gt $MaximumBytes) { | ||
| throw "The public PDB exceeds the configured size limit of $MaximumBytes bytes: $publicPdb" | ||
| } | ||
|
|
||
| @($privatePdb, $publicPdb) | ForEach-Object { | ||
| $item = Get-Item -LiteralPath $_ | ||
| $hash = Get-FileHash -LiteralPath $_ -Algorithm SHA256 | ||
| [pscustomobject]@{ | ||
| Path = $item.FullName | ||
| Bytes = $item.Length | ||
| SHA256 = $hash.Hash | ||
| Guid = $privateIdentity.Guid | ||
| Age = $privateIdentity.Age | ||
| Public = $_ -eq $publicPdb | ||
| } | ||
| } | Format-Table -AutoSize | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.