From 873dcc0f18be41f5f26a011b73392e71d63958cc Mon Sep 17 00:00:00 2001 From: Robert Scott Date: Sat, 27 Jul 2024 22:52:47 +0100 Subject: [PATCH] python311Packages.onnx: add patch for CVE-2024-5187 --- .../onnx/1.15.0-CVE-2024-5187.patch | 145 ++++++++++++++++++ .../python-modules/onnx/default.nix | 1 + 2 files changed, 146 insertions(+) create mode 100644 pkgs/development/python-modules/onnx/1.15.0-CVE-2024-5187.patch diff --git a/pkgs/development/python-modules/onnx/1.15.0-CVE-2024-5187.patch b/pkgs/development/python-modules/onnx/1.15.0-CVE-2024-5187.patch new file mode 100644 index 000000000000..4f2b3b71f017 --- /dev/null +++ b/pkgs/development/python-modules/onnx/1.15.0-CVE-2024-5187.patch @@ -0,0 +1,145 @@ +Combination of upstream 3fc3845edb048df559aa2a839e39e95503a0ee34 +and 1b70f9b673259360b6a2339c4bd97db9ea6e552f, adjusted to apply +to v1.15.0 + +diff --git a/onnx/backend/test/runner/__init__.py b/onnx/backend/test/runner/__init__.py +index 4d9dce0b..5bab19c1 100644 +--- a/onnx/backend/test/runner/__init__.py ++++ b/onnx/backend/test/runner/__init__.py +@@ -10,7 +10,6 @@ import os + import re + import shutil + import sys +-import tarfile + import tempfile + import time + import unittest +@@ -221,8 +220,7 @@ class Runner: + ) + urlretrieve(model_test.url, download_file.name) + print("Done") +- with tarfile.open(download_file.name) as t: +- t.extractall(models_dir) ++ onnx.utils._extract_model_safe(download_file.name, models_dir) + except Exception as e: + print(f"Failed to prepare data for model {model_test.model_name}: {e}") + raise +diff --git a/onnx/hub.py b/onnx/hub.py +index e5ca9e2c..8c04515d 100644 +--- a/onnx/hub.py ++++ b/onnx/hub.py +@@ -9,7 +9,6 @@ import hashlib + import json + import os + import sys +-import tarfile + from io import BytesIO + from os.path import join + from typing import IO, Any, Dict, List, Optional, Set, Tuple, cast +@@ -280,6 +279,7 @@ def download_model_with_test_data( + ) -> Optional[str]: + """ + Downloads a model along with test data by name from the onnx model hub and returns the directory to which the files have been extracted. ++ Users are responsible for making sure the model comes from a trusted source, and the data is safe to be extracted. + + :param model: The name of the onnx model in the manifest. This field is case-sensitive + :param repo: The location of the model repo in format "user/repo[:branch]". +@@ -337,12 +337,14 @@ def download_model_with_test_data( + "download the model from the model hub." + ) + +- with tarfile.open(local_model_with_data_path) as model_with_data_zipped: +- # FIXME: Avoid index manipulation with magic numbers +- local_model_with_data_dir_path = local_model_with_data_path[ +- 0 : len(local_model_with_data_path) - 7 +- ] +- model_with_data_zipped.extractall(local_model_with_data_dir_path) ++ # FIXME: Avoid index manipulation with magic numbers, ++ # remove ".tar.gz" ++ local_model_with_data_dir_path = local_model_with_data_path[ ++ 0 : len(local_model_with_data_path) - 7 ++ ] ++ onnx.utils._extract_model_safe( ++ local_model_with_data_path, local_model_with_data_dir_path ++ ) + model_with_data_path = ( + local_model_with_data_dir_path + + "/" +diff --git a/onnx/utils.py b/onnx/utils.py +index 28624f63..e1236fb2 100644 +--- a/onnx/utils.py ++++ b/onnx/utils.py +@@ -4,6 +4,7 @@ + from __future__ import annotations + + import os ++import tarfile + + import onnx.checker + import onnx.helper +@@ -212,3 +213,65 @@ def extract_model( + onnx.save(extracted, output_path) + if check_model: + onnx.checker.check_model(output_path) ++ ++ ++def _tar_members_filter( ++ tar: tarfile.TarFile, base: str | os.PathLike ++) -> list[tarfile.TarInfo]: ++ """Check that the content of ``tar`` will be extracted safely ++ ++ Args: ++ tar: The tarball file ++ base: The directory where the tarball will be extracted ++ ++ Returns: ++ list of tarball members ++ """ ++ result = [] ++ for member in tar: ++ member_path = os.path.join(base, member.name) ++ abs_base = os.path.abspath(base) ++ abs_member = os.path.abspath(member_path) ++ if not abs_member.startswith(abs_base): ++ raise RuntimeError( ++ f"The tarball member {member_path} in downloading model contains " ++ f"directory traversal sequence which may contain harmful payload." ++ ) ++ elif member.issym() or member.islnk(): ++ raise RuntimeError( ++ f"The tarball member {member_path} in downloading model contains " ++ f"symbolic links which may contain harmful payload." ++ ) ++ result.append(member) ++ return result ++ ++ ++def _extract_model_safe( ++ model_tar_path: str | os.PathLike, local_model_with_data_dir_path: str | os.PathLike ++) -> None: ++ """Safely extracts a tar file to a specified directory. ++ ++ This function ensures that the extraction process mitigates against ++ directory traversal vulnerabilities by validating or sanitizing paths ++ within the tar file. It also provides compatibility for different versions ++ of the tarfile module by checking for the availability of certain attributes ++ or methods before invoking them. ++ ++ Args: ++ model_tar_path: The path to the tar file to be extracted. ++ local_model_with_data_dir_path: The directory path where the tar file ++ contents will be extracted to. ++ """ ++ with tarfile.open(model_tar_path) as model_with_data_zipped: ++ # Mitigate tarball directory traversal risks ++ if hasattr(tarfile, "data_filter"): ++ model_with_data_zipped.extractall( ++ path=local_model_with_data_dir_path, filter="data" ++ ) ++ else: ++ model_with_data_zipped.extractall( ++ path=local_model_with_data_dir_path, ++ members=_tar_members_filter( ++ model_with_data_zipped, local_model_with_data_dir_path ++ ), ++ ) diff --git a/pkgs/development/python-modules/onnx/default.nix b/pkgs/development/python-modules/onnx/default.nix index d4257e4489d8..cbd4b03ca7cb 100644 --- a/pkgs/development/python-modules/onnx/default.nix +++ b/pkgs/development/python-modules/onnx/default.nix @@ -45,6 +45,7 @@ buildPythonPackage rec { url = "https://github.com/onnx/onnx/commit/08a399ba75a805b7813ab8936b91d0e274b08287.patch"; hash = "sha256-9X92N9i/hpQjDGe4I/C+FwUcTUTtP2Nf7+pcTA2sXoA="; }) + ./1.15.0-CVE-2024-5187.patch ]; nativeBuildInputs = [