Skip to content

[Bug]: Setting text.usetex=True in pyplot.rcParams Raises FIPS Compliance Errors #29603

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

Closed
martinky24 opened this issue Feb 11, 2025 · 3 comments · Fixed by #29608 or #29700
Closed

[Bug]: Setting text.usetex=True in pyplot.rcParams Raises FIPS Compliance Errors #29603

martinky24 opened this issue Feb 11, 2025 · 3 comments · Fixed by #29608 or #29700
Milestone

Comments

@martinky24
Copy link
Contributor

martinky24 commented Feb 11, 2025

Bug summary

If you use a FIPS (Federal Information Processing Standards) compliant Python install, then you cannot use pyplot.show to display a plot with plt.rcParams['text.usetex'] = True due to a hashlib.md5 call in texmanager.py.

This is similar to #18192 (and much of this report is modeled off of that)

There are 3 places in the code that seem to still use hashlib.md5:

There probably isn't a great reason not to replace md5 with sha256 (or something else) in these locations.

Code for reproduction

The big requirement here is a FIPS compliant system or at least a Python install compiled to be FIPS compliant. Then the following code will reproduce the error.

To reproduce,

  1. Run sudo fips-mode-setup --enable && sudo reboot (there may be other methods)
  2. After the reboot I confirmed FIPS mode had been enabled by running fips-mode-setup --check and it returned FIPS mode is enabled.
  3. python3 -m venv .venv
  4. ./.venv/bin/python -m pip install matplotlib==3.10.0
  5. ./.venv/bin/python fips_error.py. The contents of fips_error.py is listed below.
import matplotlib.pyplot as plt

plt.rcParams['text.usetex'] = True
fig, ax = plt.subplots()
plt.text(0, 0, r'$\hat{\mathbf{x}}$')
plt.show()

Actual outcome

$ python fips_error.py 
Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib64/python3.11/tkinter/__init__.py", line 1967, in __call__
    return self.func(*args)
           ^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/tkinter/__init__.py", line 861, in callit
    func(*args)
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/backends/_backend_tk.py", line 274, in idle_draw
    self.draw()
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/backends/backend_tkagg.py", line 10, in draw
    super().draw()
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/backends/backend_agg.py", line 382, in draw
    self.figure.draw(self.renderer)
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/artist.py", line 94, in draw_wrapper
    result = draw(artist, renderer, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/artist.py", line 71, in draw_wrapper
    return draw(artist, renderer)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/figure.py", line 3257, in draw
    mimage._draw_list_compositing_images(
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/image.py", line 134, in _draw_list_compositing_images
    a.draw(renderer)
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/artist.py", line 71, in draw_wrapper
    return draw(artist, renderer)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/axes/_base.py", line 3181, in draw
    mimage._draw_list_compositing_images(
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/image.py", line 134, in _draw_list_compositing_images
    a.draw(renderer)
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/artist.py", line 71, in draw_wrapper
    return draw(artist, renderer)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/axis.py", line 1416, in draw
    tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/axis.py", line 1343, in _get_ticklabel_bboxes
    return ([tick.label1.get_window_extent(renderer)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/axis.py", line 1343, in <listcomp>
    return ([tick.label1.get_window_extent(renderer)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/text.py", line 969, in get_window_extent
    bbox, info, descent = self._get_layout(self._renderer)
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/text.py", line 373, in _get_layout
    _, lp_h, lp_d = _get_text_metrics_with_cache(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/text.py", line 69, in _get_text_metrics_with_cache
    return _get_text_metrics_with_cache_impl(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/text.py", line 77, in _get_text_metrics_with_cache_impl
    return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/backends/backend_agg.py", line 211, in get_text_width_height_descent
    return super().get_text_width_height_descent(s, prop, ismath)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/backend_bases.py", line 566, in get_text_width_height_descent
    return self.get_texmanager().get_text_width_height_descent(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/texmanager.py", line 360, in get_text_width_height_descent
    dvifile = cls.make_dvi(tex, fontsize)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/texmanager.py", line 276, in make_dvi
    basefile = cls.get_basefile(tex, fontsize)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/texmanager.py", line 171, in get_basefile
    filehash = hashlib.md5(src.encode('utf-8')).hexdigest()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: [digital envelope routines: EVP_DigestInit_ex] disabled for FIPS

Expected outcome

No exception related to FIPS and the plot is created.

Additional information

$ .venv/bin/python -m pip list
Package         Version
--------------- -----------
contourpy       1.3.1
cycler          0.12.1
fonttools       4.56.0
kiwisolver      1.4.8
matplotlib      3.10.0
numpy           2.2.2
packaging       24.2
pillow          11.1.0
pip             22.3.1
pyparsing       3.2.1
python-dateutil 2.9.0.post0
setuptools      65.5.1
six             1.17.0

Operating system

RHEL 8.10 (with FIPS enabled)

Matplotlib Version

3.10.0

Matplotlib Backend

tkagg

Python version

Python 3.11.9

@martinky24
Copy link
Contributor Author

martinky24 commented Feb 11, 2025

I've not contributed to the project before, but I'll possibly try to set up a development environment and open a PR for this in the next day or two.

@martinky24
Copy link
Contributor Author

I opened a PR here: #29608

@tacaswell tacaswell added this to the v3.10.1 milestone Feb 12, 2025
@martinky24
Copy link
Contributor Author

Note to self: In another repo, someone found an incantation that can be used to potentially test FIPS issues in a container simonw/datasette#2270 (comment)

tacaswell added a commit that referenced this issue Feb 12, 2025
Remove md5 usage to prevent issues on FIPS enabled systems (closes #29603)
meeseeksmachine pushed a commit to meeseeksmachine/matplotlib that referenced this issue Feb 12, 2025
@ksunden ksunden mentioned this issue Mar 3, 2025
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants