Skip to content

fix spirv compile failure diagnostics read past shader buffer - #6882

Open
lazypool wants to merge 1 commit into
Tencent:masterfrom
lazypool:fix/spirv-oob-read-6881
Open

fix spirv compile failure diagnostics read past shader buffer#6882
lazypool wants to merge 1 commit into
Tencent:masterfrom
lazypool:fix/spirv-oob-read-6881

Conversation

@lazypool

@lazypool lazypool commented Aug 1, 2026

Copy link
Copy Markdown

Summary

Fixes #6881 — the error-printing path in compile_spirv_module() (src/gpu.cpp) treated the shader source slice as a null-terminated C string when it is not, causing an out-of-bounds read and garbled diagnostic output whenever a Vulkan compute shader fails to compile.

Root cause

  • Shader .comp_data[] arrays are generated by cmake/ncnn_generate_shader_comp_header.cmake as hex-encoded bytes without a trailing 0x00.
  • compile_spirv_module() slices the source into comp_datas[3] (everything after #version) and, on parse failure, scans it with strchr() / *p != '\0' — both require null-termination, but none is guaranteed.
  • In practice strchr() walks past the end of the buffer into adjacent memory, printing garbage (or, with ASan, reporting a stack-buffer-overflow).

Change

Bound the scan using the already-known source length (comp_data_size_2, the size of comp_datas[3]):

  • strchr(p, '\n')memchr(p, '\n', p_end - p)
  • final if (*p != '\0')if (p != p_end)
  • final %s print → %.*s with the remaining length

Verification

Built with -DNCNN_VULKAN=ON (system glslang 16.3.0) and tested under AddressSanitizer on RADV:

  • Before: compiling a broken, non-null-terminated shader source via compile_spirv_module(data, size, ...)ERROR: AddressSanitizer: stack-buffer-overflow ... in ncnn::compile_spirv_module(...)
  • After: same input prints the shader lines cleanly and bounded (1:\tvoid main() { ... }), no ASan report; a real shader still compiles (rc=0).

No behavioral change to successful compilation paths.

…t#6881)

the shader source slice passed to glslang (comp_datas[3]) is not
null-terminated, since the .comp_data arrays generated by
ncnn_generate_shader_comp_header.cmake are hex-encoded without a
trailing 0x00. the error-printing path in compile_spirv_module()
scanned it with strchr() and checked *p != '\0', causing an
out-of-bounds read and garbled diagnostics whenever a shader fails
to compile.

bound the scan with memchr() using the known source length and print
the trailing partial line with %.*s instead of relying on
null-termination. verified with asan: before, a broken non-null-
terminated shader source reports a stack-buffer-overflow in
compile_spirv_module(); after, the error path prints correctly with
no overrun.

Signed-off-by: lazypool <lazypool@proton.me>
Co-authored-by: Marcin Sochacki <136440930+marcin-sochacki@users.noreply.github.com>
@tencent-adm

Copy link
Copy Markdown
Member

CLA assistant check
Thank you for your submission, we really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@lazypool lazypool left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Please review when you get a chance, thanks!

marcin-sochacki added a commit to marcin-sochacki/aports that referenced this pull request Aug 3, 2026
arbassett pushed a commit to qnx-ports/aports that referenced this pull request Aug 20, 2026
* extra/ncnn: add port

* backport of upstream Tencent/ncnn#6882

* add python bindings + fix python related ncnn issues

* let abuild handle parallelization
@github-actions

Copy link
Copy Markdown

Please enable github action in YOUR FORKED REPO to make code-format workflow work

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Out-of-bounds read in compile_spirv_module()'s error-printing path - on non-null-terminated shader data

2 participants