Commit 76f0160
Add a diagnostic job demonstrating the TokenOwner mechanism
Temporarily add a `diag-token` job to the `cygwin-test` workflow that
creates a directory through four code paths and reports its NTFS Owner.
The idea is to empirically establish the cause of the Owner asymmetry: a
Cygwin or Cygwin-derived runtime (`cygwin1.dll` for Cygwin git;
`msys-2.0.dll` loaded by Git for Windows's bundled MSYS2 `sh.exe`)
rewrites the process token's `TokenOwner` field at DLL initialization,
and `CreateProcessW` propagates that mutation to every descendant.
The four tests are:
| Test | Sequence | Predicted Owner |
| ---- | ----------------------------------------------- | ------------------------ |
| A | PowerShell `New-Item` | `BUILTIN\Administrators` |
| B | Cygwin `mkdir` | `runneradmin` (197108) |
| C | Cygwin bash -> Git for Windows `git init` | `runneradmin` (197108) |
| D | PowerShell -> Git Bash -> PowerShell `New-Item` | `runneradmin` (197108) |
Test A is the Win32 baseline. The kernel-default `TokenOwner` for
`runneradmin`'s full administrative token is `BUILTIN\Administrators`,
because `runneradmin` is the built-in local Administrator (RID 500) and
`FilterAdministratorToken=0` exempts it from UAC token filtering.
Test B is the Cygwin baseline. Cygwin's `cygheap_user::init` calls
`NtSetInformationToken(hProcToken, TokenOwner, &effec_cygsid, ...)` at
DLL init, and the resulting Owner reflects the rewritten token.
Test C is the load-bearing case. The child is a native Windows program
that loads no Cygwin runtime of its own. It produces a user-owned
`.git`, showing that the rewrite performed by the parent Cygwin bash
propagates through `CreateProcessW`'s token duplication to a native
Windows descendant.
Test D strengthens the case: the first and last links are native Windows
programs (a fresh PowerShell using its built-in `New-Item` cmdlet). Only
the middle link is a Cygwin-family runtime (Git for Windows's MSYS2
`bash.exe`, linked against `msys-2.0.dll`). The directory is still
user-owned, showing that the mechanism does not depend on git, nor on
shell dispatch via `git submodule`, nor on any property of the
final-link binary, but only on whether *any* process in the ancestry has
loaded a Cygwin-family runtime.
This `diag-token` job, like the `reproduce-safe-dir` matrix, is
temporary and should be removed before this work is integrated.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent ce68322 commit 76f0160
1 file changed
Lines changed: 67 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
102 | 102 | | |
103 | 103 | | |
104 | 104 | | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
105 | 172 | | |
106 | 173 | | |
107 | 174 | | |
| |||
0 commit comments