Skip to content

Validate the DXBC shader length against the container part size - #8782

Open
Nilesh Patil (nileshpatil6) wants to merge 1 commit into
microsoft:mainfrom
nileshpatil6:bound-dxbc-shader-length
Open

Validate the DXBC shader length against the container part size#8782
Nilesh Patil (nileshpatil6) wants to merge 1 commit into
microsoft:mainfrom
nileshpatil6:bound-dxbc-shader-length

Conversation

@nileshpatil6

Copy link
Copy Markdown

Towards #8406.

CShaderCodeParser::SetShader takes the shader's length in tokens from pBuffer[1] and derives its end pointer from it:

m_pShaderEndToken = pBuffer + pBuffer[1];

so a wrong length there sends the parser off the end of the buffer. SetShader itself has no size to check against, so the bound has to come from the caller.

Of the two call paths, ConvertInDriverImpl has no buffer size at all: the driver hands over a bare const UINT32* and the declared length is the only length there is. It already rejects the degenerate case with IFTBOOL(SizeInUINTs >= 2, ...), and without an API change there is nothing more it can check.

ConvertImpl is the one that does have a size, and was not using it. DxilContainerReader::GetPartContent has an optional out parameter for the part size:

HRESULT GetPartContent(uint32_t idx, const void **ppResult, uint32_t *pResultSize = nullptr);

and the call here passed only two arguments, so the part size was discarded. The container reader bounds the part within the container, but nothing then checked that the shader's own declared length fits inside that part, so a part whose length token is too large still walked the parser past the end.

This asks for the size and checks two things before the buffer reaches the parser: that the part is big enough to hold the version and length tokens that SetShader reads, and that the declared length stays within the part. The comparison is written as a division so there is no multiplication to overflow. Both SetShader calls in ConvertImpl take the same buffer, so the single check covers both.

Two notes:

  • I left ConvertInDriverImpl alone for the reason above. If you would rather have the bound enforced inside the parser, that needs a size parameter on SetShader and a matching change to the driver entry point, which is a larger API question than I wanted to decide in this PR. Happy to follow up with that shape if you prefer it.
  • I could not build this locally to confirm compilation: projects/dxilconv/CMakeLists.txt is gated on if(WIN32) and I do not have MSVC on this machine, so my Linux build of the repo does not produce the target. I checked the pieces against the headers instead: the three-argument GetPartContent overload above, DXC_E_ERROR_PARSING_DXBC_BYTECODE in include/dxc/Support/ErrorCodes.h (already used a few lines away in ConvertInDriverImpl), and CShaderToken being typedef UINT in ShaderBinary.h. Please let CI confirm the build.

Copilot AI balanced review requested due to automatic review settings August 16, 2026 11:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: New

Development

Successfully merging this pull request may close these issues.

2 participants