eryksun added the comment: > wherein pointers can be passed directly in place of PyHKEY > instances e.g. _winreg.QueryValue(0x41414141, "")
If a debugger is attached you see the first-chance exception for the access violation. Normally the registry function simply returns ERROR_INVALID_HANDLE (6), which gets raised as an OSError in Python. The call took the RPC path because the low bit (1) marks a remote handle, which is actually a pointer to a data structure. RPCRT4!NDRCContextBinding looks for a signature (0xFEDCBA98) to validate this structure. In this case the attempt raised an access violation, which gets handled by raising another exception with the exception code set to ERROR_INVALID_HANDLE. The same exception gets raised if it can't validate the handle. Subsequently this exception is handled by calling RPCRT4!NdrClientMapCommFault to map the code to a return value. For example (x64 ISA): >>> _winreg.QueryInfoKey(0x41414141) (a2c.828): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. RPCRT4!NDRCContextBinding+0x4: 000007fe`fefca6e4 81790898badcfe cmp dword ptr [rcx+8],0FEDCBA98h ds:00000000`41414148=???????? 0:000> gN (a2c.828): Unknown exception - code 00000006 (first chance) Breakpoint 0 hit RPCRT4!NdrClientMapCommFault: 000007fe`ff05f010 fff3 push rbx 0:000> kc 8 Call Site RPCRT4!NdrClientMapCommFault RPCRT4!NdrpClientCall3 RPCRT4!NdrClientCall3 ADVAPI32!SafeBaseRegQueryInfoKey ADVAPI32!RemoteRegQueryInfoKeyWrapper kernel32!TlsGetValue ADVAPI32!RegQueryInfoKeyAStub python27!PyQueryInfoKey The exception code is passed in register r8 and gets assigned to the address in r9: 0:000> r r8, r9 r8=0000000000000006 r9=000000000021f1d8 0:000> dd 21f1d8 l1 00000000`0021f1d8 00000000 0:000> pt RPCRT4!NdrClientMapCommFault+0x80: 000007fe`ff05f080 c3 ret 0:000> dd 21f1d8 l1 00000000`0021f1d8 00000006 This return value gets passed back up the call stack: 0:000> gu; pt; r rax rax=0000000000000006 0:000> gu; pt; r rax rax=0000000000000006 0:000> gu; pt; r rax rax=0000000000000006 0:000> gu; pt; r rax rax=0000000000000006 0:000> gu; pt; r rax rax=0000000000000006 0:000> r rax=0000000000000006 rbx=0000000000e1cda0 rcx=0000000000000000 rdx=0000000000000000 rsi=0000000000000000 rdi=000000001e1027b0 rip=00000000779ba204 rsp=000000000021f9d8 rbp=0000000000eb61c8 r8=000000000021f1d8 r9=0000000000000000 r10=000000000021f1d8 r11=000000000021f8b0 r12=0000000000e1cda0 r13=0000000000807bb0 r14=000000001e2b3210 r15=0000000000eb7060 iopl=0 nv up ei pl nz na po nc cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206 kernel32!RegQueryInfoKeyA+0x364: 00000000`779ba204 c3 ret Until finally getting raised as a Python exception: 0:000> g Traceback (most recent call last): File "<stdin>", line 1, in <module> WindowsError: [Error 6] The handle is invalid The odds are extremely low that someone will pass in an integer address that's flagged as a remote handle (ends in 1) and is a valid, mapped address that contains the RPC handle signature. Even then, it won't reference an actual proxy handle for a remote registry, so it'll just fail farther along the chain. I'm sure if a feature exists that someone, somewhere depends on it, so I don't see a reason to change this unless there's a real problem here. Is there a specific technical or security problem that you see here? ---------- nosy: +eryksun _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue24201> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com