8000 Introduce custom sympy srepr parser [stable/2.0] by mtreinish · Pull Request #14023 · Qiskit/qiskit · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Introduce custom sympy srepr parser [stable/2.0] #14023

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 14, 2025

Conversation

mtreinish
Copy link
Member

Summary

This commit introduces a custom parser to QPY for parameter expression payloads that were generated using sympy. Prior to QPY version 10 this was the only way we supported serializing parameter expressions in QPY. For QPY version 10, 11, and 12 sympy could optionally be used if the payload was generated explicitly to not use symengine (in qiskit 1.0 it defaulted to use symengine).

This serialization format relied on sympy to generate a string representation of the expression which we then put in the payload. On deserialization we called sympy's parse_expr() function which internally is calling sympy's sympify() internally. Sympy documents that sympify() relies on Python's eval() for string input and should not be used with untrusted input. But parse_expr() didn't have such a warning (at the time, I plan to contribute adding one), so using this function provides an avenue for arbitrary code execution during QPY deserialization.

This commit fixes this issue by writing a custom parser for the string representation in a QPY payload based on python's ast module. This parser walks the abstract syntax tree and builds the sympy expression object as it it goes. It is restricted to the operations that ParameterExpression supports and if any part of the string tries to use functionality outside that set it will error.

Details and comments

This commit introduces a custom parser to QPY for parameter expression
payloads that were generated using sympy. Prior to QPY version 10 this
was the only way we supported serializing parameter expressions in QPY.
For QPY version 10, 11, and 12 sympy could optionally be used if the
payload was generated explicitly to not use symengine (in qiskit 1.0 it
defaulted to use symengine).
This serialization format relied on sympy to generate a string
representation of the expression which we then put in the payload. On
deserialization we called sympy's `parse_expr()` function which
internally is calling sympy's `sympify()` internally. Sympy documents
that `sympify()` relies on Python's `eval()` for string input and
should not be used with untrusted input. But `parse_expr()` didn't have
such a warning (at the time, I plan to contribute adding one), so
using this function provides an avenue for arbitrary code execution
during QPY deserialization.

This commit fixes this issue by writing a custom parser for the string
repesentation in a QPY payload based on python's ast module. This parser
walks the abstract syntax tree and builds the sympy expression object as
it it goes. It is restricted to the operations that
`ParameterExpression` supports and if any part of the string tries to
use functionality outside that set it will error.
@mtreinish mtreinish added the Changelog: Bugfix Include in the "Fixed" section of the changelog label Mar 14, 2025
@mtreinish mtreinish added this to the 2.0.0 milestone Mar 14, 2025
@mtreinish mtreinish requested a review from a team as a code owner March 14, 2025 15:18
@qiskit-bot
Copy link
Collaborator

One or more of the following people are relevant to this code:

  • @Qiskit/terra-core
  • @mtreinish
  • @nkanazawa1989

Copy link
Contributor
@ElePT ElePT left a comment

Choose a reason for hiding this comment

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

LGTM! I just have two minor comments and then I think it's ready.

@ElePT
Copy link
Contributor
ElePT commented Mar 14, 2025

Is the plan to also add version changes to this PR and use it to release like in #14022?

@mtreinish
Copy link
Member 8000 Author

Is the plan to also add version changes to this PR and use it to release like in #14022?

Let me do that now and apply your suggestions, that will save us some CI time.

mtreinish and others added 2 commits March 14, 2025 12:03
Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>
@mtreinish mtreinish requested a review from ElePT March 14, 2025 16:05
ElePT
ElePT previously approved these changes Mar 14, 2025
Copy link
Contributor
@ElePT ElePT left a comment

Choose a reason for hiding this comment

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

LGTM

PGO fails when we build qiskit-cext both as cdylib in addition to rlib,
due to missing Python symbols. This could be due to us not setting the
pyo3/extension-module correctly; which we want enabled when we compile
the crate for use in the Python extension crate qiskit-pyext, but
don't want for the standalone cdylib usage.

This PR changes to only building the rlib per default, meaning that
building the qiskit-pyext crate (and running PGO) will not build the
cdylib. To build the cdylib for C standalone mode, one has to request
that crate type via cargo rustc .... --crate-type cdylib. We're
investigating further solutions but this now fixes PGO and the C
standalone tests pass as well.
@mtreinish mtreinish merged commit 9f2177a into Qiskit:stable/2.0 Mar 14, 2025
18 checks passed
@mtreinish mtreinish deleted the advisory_fix_stable_2.0 branch March 14, 2025 17:50
@raynelfss raynelfss mentioned this pull request Mar 28, 2025
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: Bugfix Include in the "Fixed" section of the changelog priority: high
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
0