Skip to content

CryptGenRandom says true when it worked - #317

Merged
tamnd merged 1 commit into
mainfrom
random-inverted
Sep 9, 2026
Merged

tamnd merged 1 commit into
mainfrom
random-inverted

Conversation

@tamnd

@tamnd tamnd commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Fixes #316.

mojo build and mojo run both aborted during startup on Windows with Assertion failed: !err.isError(), file Support/lib/Telemetry/TelemetryContext.cpp, line 172 and exit code 0xC000001D. The assert is in createLocalIDs, which asks for 32 random bytes to build a session identifier. It got an error every single time.

The Windows arm of SecureRandomBytesGenerator::getRandomBytes tested CryptGenRandom the wrong way round. It returns a BOOL that is nonzero on success, and the code returned an Error when it was nonzero. So every successful call was reported as a failure and, worse, every real failure was reported as success with the buffer left untouched, meaning the caller would have got stack garbage and been told it was cryptographically secure.

What changed

The condition, plus a comment saying why the reader should not assume the old one was a deliberate inversion of something. The error message now carries GetLastError(), because a bare false is all this API gives you and the other two platforms either cannot fail or return the reason themselves.

How it was checked

By running the compiler. A cross linked mojo.exe was staged onto a Windows host in a MODULAR_HOME layout with the compiler runtime DLL and a Windows built standard library, and mojo build and mojo run were pointed at the hello example. Before this change both aborted at the assert above. After it they get past startup.

mojo --version already worked, which is why this was not caught earlier: the version path does not build a telemetry session.

Worth knowing

There is a unit test for this, Support/unittests/RandomTest.cpp, and it checks precisely the thing that was broken. It has never run on Windows. The tiers in test-tiers.txt cover the Mojo standard library only, and the C++ unit tests are not in any of them. That is the second bug a C++ unit test would have caught, and it is filed separately rather than fixed here.

@tamnd tamnd added this to the M6 Tier 2 and native hosting milestone Sep 9, 2026
@tamnd tamnd added area/runtime AsyncRT, allocator, crash handling type/bug Something is broken priority/p0 Blocking. Nothing downstream moves until this is done silent-failure Fails without an error message. Handle with care labels Sep 9, 2026
The Windows arm of SecureRandomBytesGenerator::getRandomBytes tested the return value the wrong way round. CryptGenRandom returns a BOOL that is nonzero on success, so every successful call was reported as an error and every failure was reported as success.

The first caller to trip over it is the telemetry code, which builds a session identifier out of 32 random bytes during startup, asserts that the call worked and takes the process down when it did not. That is why mojo build and mojo run both aborted on Windows before reading a single line of source.

The failure arm was the worse half. A real failure left the buffer untouched and returned success, so the caller got whatever was on the stack and was told it was cryptographically secure. Nothing depends on that today beyond an identifier, but the function is named what it is named.

Also put the Win32 error code in the message. There is nothing else to go on when this fails, since the call returns a bare false and the other two platforms either cannot fail or say why.

Fixes #316
@tamnd
tamnd merged commit 3d53bd5 into main Sep 9, 2026
7 checks passed
@tamnd
tamnd deleted the random-inverted branch September 9, 2026 03:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/runtime AsyncRT, allocator, crash handling priority/p0 Blocking. Nothing downstream moves until this is done silent-failure Fails without an error message. Handle with care type/bug Something is broken

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CryptGenRandom's return value is checked backwards, so the compiler aborts at startup on Windows

1 participant