diff --git a/pkgs/development/python-modules/tensorflow/2.10.1-CVE-2023-25669.patch b/pkgs/development/python-modules/tensorflow/2.10.1-CVE-2023-25669.patch new file mode 100644 index 0000000000000..92320a8dfb9f4 --- /dev/null +++ b/pkgs/development/python-modules/tensorflow/2.10.1-CVE-2023-25669.patch @@ -0,0 +1,250 @@ +Based on upstream 1295ae4dbb52fe06b19733b0257e2340d7b63b8d with +header reference changed to match location as of 2.10.1 + +diff --git a/tensorflow/compiler/tests/pooling_ops_test.py b/tensorflow/compiler/tests/pooling_ops_test.py +index 3d2695b15e9..3a7e22c02e5 100644 +--- a/tensorflow/compiler/tests/pooling_ops_test.py ++++ b/tensorflow/compiler/tests/pooling_ops_test.py +@@ -18,7 +18,9 @@ import numpy as np + + from tensorflow.compiler.tests import xla_test + from tensorflow.python.framework import dtypes ++from tensorflow.python.framework import errors + from tensorflow.python.framework import ops ++from tensorflow.python.framework import test_util + from tensorflow.python.ops import array_ops + from tensorflow.python.ops import gen_nn_ops + from tensorflow.python.ops import nn_ops +@@ -560,6 +562,34 @@ class PoolGradTest(xla_test.XLATestCase): + + self._TestPooling(nn_ops.avg_pool, AvgPoolGrad) + ++ @test_util.disable_mlir_bridge( ++ "TODO(b/266613412): investigate FPE in AvgPoolGrad for TPU" ++ ) ++ def testAvgPoolGradSamePaddingZeroStrideZeroSize(self): ++ output_gradient_vals = np.array([0.39117979], dtype=np.float32) ++ output_gradient_vals = output_gradient_vals.reshape([1, 1, 1, 1]) ++ with self.session() as sess: ++ with self.test_scope(): ++ output_gradients = array_ops.placeholder( ++ dtypes.float32, shape=output_gradient_vals.shape ++ ) ++ t = gen_nn_ops.avg_pool_grad( ++ orig_input_shape=[1, 0, 0, 0], ++ grad=output_gradients, ++ ksize=[1, 0, 0, 0], ++ strides=[1, 0, 0, 0], ++ padding="SAME", ++ data_format="NCHW", ++ ) ++ with self.assertRaisesRegex( ++ errors.InvalidArgumentError, ++ ( ++ "Sliding window ksize field for dimension 1 must be positive but" ++ " is 0" ++ ), ++ ): ++ sess.run(t, {output_gradients: output_gradient_vals}) ++ + # The CPU implementation of AvgPoolGrad doesn't accept kernels smaller than + # the stride size, so we only run the following tests on MaxPoolGrad. + +diff --git a/tensorflow/compiler/tf2xla/kernels/pooling_ops.cc b/tensorflow/compiler/tf2xla/kernels/pooling_ops.cc +index 43422de2650..8243d925955 100644 +--- a/tensorflow/compiler/tf2xla/kernels/pooling_ops.cc ++++ b/tensorflow/compiler/tf2xla/kernels/pooling_ops.cc +@@ -33,15 +33,41 @@ limitations under the License. + #include "tensorflow/compiler/xla/util.h" + #include "tensorflow/core/framework/bounds_check.h" + #include "tensorflow/core/framework/op_kernel.h" ++#include "tensorflow/core/framework/op_requires.h" + #include "tensorflow/core/framework/register_types.h" + #include "tensorflow/core/framework/tensor.h" + #include "tensorflow/core/platform/errors.h" + #include "tensorflow/core/util/determinism.h" + #include "tensorflow/core/util/tensor_format.h" ++#include "tensorflow/core/platform/errors.h" + + namespace tensorflow { + namespace { + ++template ++static Status ValidateKernelSizes(const T& ksizes) { ++ for (size_t i = 0; i < ksizes.size(); ++i) { ++ if (ksizes[i] <= 0) { ++ return errors::InvalidArgument( ++ "Sliding window ksize field for dimension ", i, ++ " must be positive but is ", ksizes[i]); ++ } ++ } ++ return OkStatus(); ++} ++ ++template ++static Status ValidateStrides(const T& strides) { ++ for (size_t i = 0; i < strides.size(); ++i) { ++ if (strides[i] <= 0) { ++ return errors::InvalidArgument( ++ "Sliding window stride field for dimension ", i, ++ " must be positive but is ", strides[i]); ++ } ++ } ++ return OkStatus(); ++} ++ + // Superclass of pooling ops. + class PoolingOp : public XlaOpKernel { + public: +@@ -83,50 +109,54 @@ class PoolingOp : public XlaOpKernel { + + protected: + StatusOr> GetKernelSize(XlaOpKernelContext* ctx) { +- if (ctx->num_inputs() == 1) { +- return ksize_; +- } +- const TensorShape ksize_shape = ctx->InputShape(1); +- // Validate input sizes. +- if (!TensorShapeUtils::IsVector(ksize_shape)) { +- return errors::InvalidArgument("ksize must be a vector, not shape ", +- ksize_shape.DebugString()); +- } +- if (ksize_shape.num_elements() != num_dims()) { +- return errors::InvalidArgument( +- "Sliding window ksize field must " +- "specify ", +- num_dims(), " dimensions"); +- } + std::vector ksize; +- auto status = ctx->ConstantInputAsIntVector(1, &ksize); +- if (!status.ok()) { +- return status; ++ if (ctx->num_inputs() == 1) { ++ ksize = ksize_; ++ } else { ++ const TensorShape ksize_shape = ctx->InputShape(1); ++ // Validate input sizes. ++ if (!TensorShapeUtils::IsVector(ksize_shape)) { ++ return errors::InvalidArgument("ksize must be a vector, not shape ", ++ ksize_shape.DebugString()); ++ } ++ if (ksize_shape.num_elements() != num_dims()) { ++ return errors::InvalidArgument( ++ "Sliding window ksize field must " ++ "specify ", ++ num_dims(), " dimensions"); ++ } ++ auto status = ctx->ConstantInputAsIntVector(1, &ksize); ++ if (!status.ok()) { ++ return status; ++ } + } ++ TF_RETURN_IF_ERROR(ValidateKernelSizes(ksize)); + return ksize; + } + + StatusOr> GetStride(XlaOpKernelContext* ctx) { +- if (ctx->num_inputs() == 1) { +- return stride_; +- } +- const TensorShape stride_shape = ctx->InputShape(2); +- // Validate input sizes. +- if (!TensorShapeUtils::IsVector(stride_shape)) { +- return errors::InvalidArgument("stride must be a vector, not shape ", +- stride_shape.DebugString()); +- } +- if (stride_shape.num_elements() != num_dims()) { +- return errors::InvalidArgument( +- "Sliding window stride field must " +- "specify ", +- num_dims(), " dimensions"); +- } + std::vector stride; +- auto status = ctx->ConstantInputAsIntVector(2, &stride); +- if (!status.ok()) { +- return status; ++ if (ctx->num_inputs() == 1) { ++ stride = stride_; ++ } else { ++ const TensorShape stride_shape = ctx->InputShape(2); ++ // Validate input sizes. ++ if (!TensorShapeUtils::IsVector(stride_shape)) { ++ return errors::InvalidArgument("stride must be a vector, not shape ", ++ stride_shape.DebugString()); ++ } ++ if (stride_shape.num_elements() != num_dims()) { ++ return errors::InvalidArgument( ++ "Sliding window stride field must " ++ "specify ", ++ num_dims(), " dimensions"); ++ } ++ auto status = ctx->ConstantInputAsIntVector(2, &stride); ++ if (!status.ok()) { ++ return status; ++ } + } ++ TF_RETURN_IF_ERROR(ValidateStrides(stride)); + return stride; + } + +@@ -355,10 +385,12 @@ class MaxPoolGradOp : public XlaOpKernel { + errors::InvalidArgument("Sliding window ksize field must " + "specify ", + num_dims(), " dimensions")); ++ OP_REQUIRES_OK(ctx, ValidateKernelSizes(ksize_)); + OP_REQUIRES(ctx, stride_.size() == num_dims(), + errors::InvalidArgument("Sliding window strides field must " + "specify ", + num_dims(), " dimensions")); ++ OP_REQUIRES_OK(ctx, ValidateStrides(stride_)); + + const TensorShape tensor_in_shape = ctx->InputShape(0); + const TensorShape tensor_out_shape = ctx->InputShape(1); +@@ -446,11 +478,13 @@ class AvgPoolGradOp : public XlaOpKernel { + errors::InvalidArgument("Sliding window ksize field must " + "specify ", + num_dims(), " dimensions")); ++ OP_REQUIRES_OK(ctx, ValidateKernelSizes(ksize_)); + OP_REQUIRES_OK(ctx, ctx->GetAttr("strides", &stride_)); + OP_REQUIRES(ctx, stride_.size() == num_dims(), + errors::InvalidArgument("Sliding window strides field must " + "specify ", + num_dims(), " dimensions")); ++ OP_REQUIRES_OK(ctx, ValidateStrides(stride_)); + OP_REQUIRES_OK(ctx, ctx->GetAttr("padding", &padding_)); + OP_REQUIRES(ctx, padding_ != EXPLICIT, + errors::Unimplemented( +@@ -579,10 +613,12 @@ class MaxPoolGradGradOp : public XlaOpKernel { + errors::InvalidArgument("Sliding window ksize field must " + "specify ", + num_dims(), " dimensions")); ++ OP_REQUIRES_OK(ctx, ValidateKernelSizes(ksize_)); + OP_REQUIRES(ctx, stride_.size() == num_dims(), + errors::InvalidArgument("Sliding window strides field must " + "specify ", + num_dims(), " dimensions")); ++ OP_REQUIRES_OK(ctx, ValidateStrides(stride_)); + + const TensorShape tensor_in_shape = ctx->InputShape(0); + const TensorShape tensor_out_shape = ctx->InputShape(1); +diff --git a/tensorflow/compiler/xla/client/padding.cc b/tensorflow/compiler/xla/client/padding.cc +index b9c1ce25b00..919434cb1f0 100644 +--- a/tensorflow/compiler/xla/client/padding.cc ++++ b/tensorflow/compiler/xla/client/padding.cc +@@ -35,6 +35,16 @@ Status ValidatePaddingValues(absl::Span input_dimensions, + input_dimensions.size(), window_dimensions.size(), + window_strides.size()); + } ++ for (size_t i = 0; i < input_dimensions.size(); ++i) { ++ if (window_dimensions[i] <= 0) { ++ return InvalidArgument("Window dimension %u has non-positive size %d", i, ++ window_dimensions[i]); ++ } ++ if (window_strides[i] <= 0) { ++ return InvalidArgument("Window dimension %u has non-positive stride %d", ++ i, window_strides[i]); ++ } ++ } + return OkStatus(); + } + diff --git a/pkgs/development/python-modules/tensorflow/2.10.1-CVE-2023-25675.patch b/pkgs/development/python-modules/tensorflow/2.10.1-CVE-2023-25675.patch new file mode 100644 index 0000000000000..b4353c7ee3515 --- /dev/null +++ b/pkgs/development/python-modules/tensorflow/2.10.1-CVE-2023-25675.patch @@ -0,0 +1,121 @@ +Based on upstream 8ae76cf085f4be26295d2ecf2081e759e04b8acf with +minor adjustments to apply to 2.10.1 + +diff --git a/tensorflow/compiler/tests/BUILD b/tensorflow/compiler/tests/BUILD +index d148d12a7d1..432e3891e77 100644 +--- a/tensorflow/compiler/tests/BUILD ++++ b/tensorflow/compiler/tests/BUILD +@@ -2344,3 +2344,19 @@ tf_xla_py_test( + "//tensorflow/python:training", + ], + ) ++ ++tf_xla_py_test( ++ name = "bincount_op_test", ++ size = "small", ++ srcs = ["bincount_op_test.py"], ++ enable_mlir_bridge = False, ++ python_version = "PY3", ++ shard_count = 10, ++ tags = [ ++ "no_pip", # TODO(b/149738646): fix pip install so these tests run on kokoro pip ++ ], ++ deps = [ ++ ":xla_test", ++ "//tensorflow/python:platform_test", ++ ], ++) +diff --git a/tensorflow/compiler/tests/bincount_op_test.py b/tensorflow/compiler/tests/bincount_op_test.py +new file mode 100644 +index 00000000000..79e8a7e91b8 +--- /dev/null ++++ b/tensorflow/compiler/tests/bincount_op_test.py +@@ -0,0 +1,40 @@ ++# Copyright 2023 The TensorFlow Authors. All Rights Reserved. ++# ++# Licensed under the Apache License, Version 2.0 (the "License"); ++# you may not use this file except in compliance with the License. ++# You may obtain a copy of the License at ++# ++# http://www.apache.org/licenses/LICENSE-2.0 ++# ++# Unless required by applicable law or agreed to in writing, software ++# distributed under the License is distributed on an "AS IS" BASIS, ++# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++# See the License for the specific language governing permissions and ++# limitations under the License. ++# ============================================================================== ++"""Tests for bincount using the XLA JIT.""" ++from tensorflow.compiler.tests import xla_test ++from tensorflow.python.framework import errors ++from tensorflow.python.ops import gen_math_ops ++from tensorflow.python.platform import googletest ++ ++ ++class BincountTest(xla_test.XLATestCase): ++ ++ def testInputRank0(self): ++ with self.session(): ++ with self.test_scope(): ++ bincount = gen_math_ops.bincount(arr=6, size=804, weights=[52, 351]) ++ ++ with self.assertRaisesRegex( ++ errors.InvalidArgumentError, ++ ( ++ "`weights` must be the same shape as `arr` or a length-0" ++ " `Tensor`, in which case it acts as all weights equal to 1." ++ ), ++ ): ++ self.evaluate(bincount) ++ ++ ++if __name__ == "__main__": ++ googletest.main() +diff --git a/tensorflow/compiler/tf2xla/kernels/bincount_op.cc b/tensorflow/compiler/tf2xla/kernels/bincount_op.cc +index 2d4bba26239..42b37d2e0b2 100644 +--- a/tensorflow/compiler/tf2xla/kernels/bincount_op.cc ++++ b/tensorflow/compiler/tf2xla/kernels/bincount_op.cc +@@ -62,21 +62,15 @@ class DenseBincountOp : public XlaOpKernel { + StatusOr input_shape_or = ctx->builder()->GetShape(input); + OP_REQUIRES_OK(ctx, input_shape_or.status()); + auto input_shape = input_shape_or.ValueOrDie(); +- auto size = input_shape.dimensions(0); + +- if (!size) { +- output = xla::Broadcast(zero, {output_size}); +- ctx->SetOutput(0, output); +- return; +- } + auto rank = input_shape.rank(); + + OP_REQUIRES(ctx, rank <= 2, + errors::InvalidArgument( + "Shape must be at most rank 2 but is rank ", rank)); +- + xla::XlaOp weights = ctx->Input(2); + StatusOr weights_shape_or = ctx->builder()->GetShape(weights); ++ + OP_REQUIRES_OK(ctx, weights_shape_or.status()); + + auto weights_shape = weights_shape_or.ValueOrDie(); +@@ -91,11 +85,20 @@ class DenseBincountOp : public XlaOpKernel { + "1. Received ", + weights_shape.DebugString())); + ++ auto size = input_shape.dimensions(0); ++ ++ if (!size) { ++ output = xla::Broadcast(zero, {output_size}); ++ ctx->SetOutput(0, output); ++ return; ++ } ++ + auto weights_size = weights_shape.dimensions(0); + bool has_weights = false; + if (weights_size) { + has_weights = true; + } ++ + xla::Shape output_shape = xla::ShapeUtil::MakeShape(dtype, {output_size}); + xla::ScatterDimensionNumbers scatter_dnums; + scatter_dnums.set_index_vector_dim(1); diff --git a/pkgs/development/python-modules/tensorflow/bin.nix b/pkgs/development/python-modules/tensorflow/bin.nix index 96f54632069ea..d5bd8a207f515 100644 --- a/pkgs/development/python-modules/tensorflow/bin.nix +++ b/pkgs/development/python-modules/tensorflow/bin.nix @@ -198,5 +198,27 @@ in buildPythonPackage { license = licenses.asl20; maintainers = with maintainers; [ jyp abbradar cdepillabout ]; platforms = [ "x86_64-linux" "x86_64-darwin" ]; + knownVulnerabilities = optionals (versionOlder packages.version "2.12.0") [ + "CVE-2023-27579" + "CVE-2023-25801" + "CVE-2023-25676" + "CVE-2023-25675" + "CVE-2023-25674" + "CVE-2023-25673" + "CVE-2023-25671" + "CVE-2023-25670" + "CVE-2023-25669" + # already fixed in 2.10.1 https://github.com/tensorflow/tensorflow/commit/1c2e7f425529ce166f597b512e3bf524f34cda1a + #"CVE-2023-25668" + "CVE-2023-25667" + "CVE-2023-25665" + "CVE-2023-25666" + "CVE-2023-25664" + "CVE-2023-25663" + "CVE-2023-25662" + "CVE-2023-25660" + "CVE-2023-25659" + "CVE-2023-25658" + ]; }; } diff --git a/pkgs/development/python-modules/tensorflow/default.nix b/pkgs/development/python-modules/tensorflow/default.nix index 39461fd7953db..c8f329f37e2b3 100644 --- a/pkgs/development/python-modules/tensorflow/default.nix +++ b/pkgs/development/python-modules/tensorflow/default.nix @@ -193,6 +193,95 @@ let hash = "sha256-AYHUtJEXYZdVDigKZo7mQnV+PDeQg8mi45YH18qXHZA="; }; + patches = [ + (fetchpatch { + name = "CVE-2023-27579.patch"; + url = "https://github.com/tensorflow/tensorflow/commit/34f8368c535253f5c9cb3a303297743b62442aaa.patch"; + sha256 = "sha256-oGTTRdELzK2hqcnCJD+9CqKNT0CnxHrXvr5n4V+dNNE="; + }) + (fetchpatch { + name = "CVE-2023-25801.patch"; + url = "https://github.com/tensorflow/tensorflow/commit/ee50d1e00f81f62a4517453f721c634bbb478307.patch"; + sha256 = "sha256-OnaVG4xjnpX8NShVDsyUCxt/IUym4jh8pUyObxATIhA="; + }) + (fetchpatch { + name = "CVE-2023-25676.patch"; + url = "https://github.com/tensorflow/tensorflow/commit/da66bc6d5ff466aee084f9e7397980a24890cd15.patch"; + sha256 = "sha256-U0j6qVCopTUIqoZgbEdBhIr3kgqqC1gJM6AJo08ycfs="; + }) + ./2.10.1-CVE-2023-25675.patch + (fetchpatch { + name = "CVE-2023-25673.CVE-2023-25674.patch"; + url = "https://github.com/tensorflow/tensorflow/commit/728113a3be690facad6ce436660a0bc1858017fa.patch"; + sha256 = "sha256-b8PzCdLVNgHJ59z0qmet+X5Ta8WgO7xYZUAIuInncBE="; + }) + (fetchpatch { + name = "CVE-2023-25671.part-1.patch"; + url = "https://github.com/tensorflow/tensorflow/commit/760322a71ac9033e122ef1f4b1c62813021e5938.patch"; + sha256 = "sha256-ClYGmQbYRwsDb3ng2Dmx+ajNeSLnajEkw11I6P2CyqM="; + }) + (fetchpatch { + name = "CVE-2023-25671.part-2.patch"; + url = "https://github.com/tensorflow/tensorflow/commit/2eedc8f676d2c3b8be9492e547b2bc814c10b367.patch"; + sha256 = "sha256-C/4EKC471hJvWt9zmHGEKDHE9rPbK6IvqpyfeOuUREk="; + }) + (fetchpatch { + name = "CVE-2023-25670.patch"; + url = "https://github.com/tensorflow/tensorflow/commit/8a47a39d9697969206d23a523c977238717e8727.patch"; + sha256 = "sha256-usCKeytvLNhcFk5HM6ktbWp1JFYuXfRBrTgsM4yLNC8="; + }) + ./2.10.1-CVE-2023-25669.patch + # 2.10.1 already addressed CVE-2023-25668 in + # https://github.com/tensorflow/tensorflow/commit/1c2e7f425529ce166f597b512e3bf524f34cda1a + (fetchpatch { + name = "CVE-2023-25667.patch"; + url = "https://github.com/tensorflow/tensorflow/commit/8dc723fcdd1a6127d6c970bd2ecb18b019a1a58d.patch"; + sha256 = "sha256-U6M/Giz7x9jnMP3OuZPd8YidfsGqEdz2ki2XAVRN3Ew="; + }) + (fetchpatch { + name = "CVE-2023-25665.patch"; + url = "https://github.com/tensorflow/tensorflow/commit/5e0ecfb42f5f65629fd7a4edd6c4afe7ff0feb04.patch"; + sha256 = "sha256-zAPsSZisrPs951UnXuWYiCjy7ehRuDdMRUevwVcrr0Q="; + }) + (fetchpatch { + name = "CVE-2023-25666.patch"; + url = "https://github.com/tensorflow/tensorflow/commit/d0d4e779da0d0f56499c6fa5ba09f0a576cc6b14.patch"; + sha256 = "sha256-0K35pWWQ9Wy2wqur4vtWoOwOCokJxdbxGayIJjEuqAg="; + }) + (fetchpatch { + name = "CVE-2023-25664.patch"; + url = "https://github.com/tensorflow/tensorflow/commit/ddaac2bdd099bec5d7923dea45276a7558217e5b.patch"; + sha256 = "sha256-AcJPp6akNMt8wPb/lf18Km1n8V0WnKSppT7udSQLDXw="; + }) + (fetchpatch { + name = "CVE-2023-25663.patch"; + url = "https://github.com/tensorflow/tensorflow/commit/239139d2ae6a81ae9ba499ad78b56d9b2931538a.patch"; + sha256 = "sha256-qitBX8pSLCWov1zg+FpVQcFfzzS6crJFkBYUzeA/Ovc="; + }) + (fetchpatch { + name = "CVE-2023-25662.patch"; + url = "https://github.com/tensorflow/tensorflow/commit/08b8e18643d6dcde00890733b270ff8d9960c56c.patch"; + sha256 = "sha256-dbukV9dTnp/eIcpqnrrrUtWlHX2WUOQtrN5wdXKy2cc="; + }) + (fetchpatch { + name = "CVE-2023-25660.patch"; + url = "https://github.com/tensorflow/tensorflow/commit/6d423b8bcc9aa9f5554dc988c1c16d038b508df1.patch"; + sha256 = "sha256-Nys2HtI4jcngSEm/T9/H5yy6DcdsSr9rNj4pnBkwV7Y="; + }) + (fetchpatch { + name = "CVE-2023-25659.patch"; + url = "https://github.com/tensorflow/tensorflow/commit/ee004b18b976eeb5a758020af8880236cd707d05.patch"; + sha256 = "sha256-dxxvK4vqCnk025nTwAiLt2mOgHOX6WHvidAl1GdHahA="; + }) + (fetchpatch { + name = "CVE-2023-25658.patch"; + # this is the more minimal fix applied to 2.11.1 as opposed to the large + # squashed commit indicated in the CVE announcement + url = "https://github.com/tensorflow/tensorflow/commit/73ed953f5171bade7a32fdcc331ff640c4ed099e.patch"; + sha256 = "sha256-+e0SlrQj/Z+6zNnvnj5TRiPglm4C5BB14r4rFVINCDE="; + }) + ]; + # On update, it can be useful to steal the changes from gentoo # https://gitweb.gentoo.org/repo/gentoo.git/tree/sci-libs/tensorflow