Skip to content

Fix out-of-bounds iterator arithmetic in getOpForPISP - #1133

Open
mhucka wants to merge 3 commits into
tensorflow:masterfrom
mhucka:fix-ps-decompose-qubits
Open

mhucka wants to merge 3 commits into
tensorflow:masterfrom
mhucka:fix-ps-decompose-qubits

Conversation

@mhucka

@mhucka mhucka commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

This fixes b/510434181, "Out-of-Bounds Iterator Arithmetic and Segfault in getOpForPISP". The vulnerability report flagged the getOpForPISP helper function for constructing new qubit ranges using arithmetic on iterators (such as cur_op_qubits.begin() + use_target) without validating that the array has sufficient elements. If a caller submits a program proto with a PISP gate containing fewer than 2 qubits (or 0), these expressions produce iterators outside valid bounds.

Normally, Cirq in Python prevents you from putting a 2-qubit gate on 0, 1, or 3 qubits. However, tfq_ps_decompose accepts raw serialized strings (tf.string) directly from Python, so a caller or fuzzer or AI agent can pass a hand-crafted Program protobuf where an Operation has the wrong number of qubits attached. This is unlikely to happen in realistic uses because other parts of TFQ would probably catch such invalid constructs, but it is not too difficult to guard against, and we may as well address this in-principle vulnerability to save ourselves the trouble of dealing with future reports about the same issue.

This PR changes tfq_ps_decompose_op.cc as follows:

  1. Inside the loop over operations in Compute, each of the four gate branches now checks cur_op.qubits_size() (the C++ protobuf equivalent of len(cur_op.qubits)) before doing anything else.

  2. In getOpForPISP, iterator math has been replaced with direct indexing.

  3. Errors are more safely reported across parallel CPU threads, using NESTED_FN_STATUS_SYNC.

In addition to that, there are some new tests.

This work was done with the help of Google Gemini.

This fixes b/510434181, "Out-of-Bounds Iterator Arithmetic and Segfault
in getOpForPISP". The vulnerability report flagged the getOpForPISP
helper function for constructing new qubit ranges using arithmetic on
iterators (such as `cur_op_qubits.begin() + use_target`) without
validating that the array has sufficient elements. If a program were
submitted submits a program proto with a PISP gate containing fewer than
2 qubits (or 0), these expressions produce iterators outside valid
bounds.

Normally, Cirq in Python prevents you from putting a 2-qubit gate on 0,
1, or 3 qubits. However, tfq_ps_decompose accepts raw serialized
strings:(`tf.string`) directly from Python, so a caller or fuzzer or AI
agent can pass a hand-crafted Program protobuf where an Operation has
the wrong number of qubits attached. This is unlikely to happen in
realistic uses because other parts of TFQ would probably catch such
invalid constructs, but it is not too difficult to guard against, and we
may as well address this in-principle vulnerability to save ourselves
the trouble of dealing with future reports about the same issue.

This PR changes tfq_ps_decompose_op.cc as follows:

1.  Inside the loop over operations in Compute, each of the four gate
    branches now checks cur_op.qubits_size() (the C++ protobuf
    equivalent of len(cur_op.qubits)) before doing anything else.

2.  In getOpForPISP, replacing iterator math with direct indexing.

3.  Report errors more safely across parallel CPU threads, using
    NESTED_FN_STATUS_SYNC.

In addition to that, there are some new tests.

This work was done with the help of Google Gemini.
@mhucka
mhucka marked this pull request as ready for review October 29, 2026 04:44
gemini-code-assist[bot]

This comment was marked as low quality.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant