已开启
Fix CVE-2021-41206 #129
Fix CVE-2021-41206 #129
已开启
XingSongSun创建于 6月2日
7 个文件变更+729-2
@@ -0,0 +1,90 @@
1+From 4d74d8a00b07441cba090a02e0dd9ed385145bf4 Mon Sep 17 00:00:00 2001
2+From: Reed Wanderman-Milne <reedwm@google.com>
3+Date: Wed, 14 Jul 2021 20:49:08 -0700
4+Subject: [PATCH] Fix crash in softmax-xent when some input dimensions are 1.
5+ 
6+Before, tf.nn.softmax_cross_entropy_with_logits would fail a CHECK if one input tensor had shape (1, 1) and the other did not.
7+ 
8+In particular, the call to ToIndexArray<2> here https://github.com/tensorflow/tensorflow/blob/1f3da84a89702d3b4f234ee83762d738caffe098/tensorflow/core/kernels/xent_op.cc#L99 would fail, since the call assumed the array had two dimensions. If both dimensions were 1, BCast would merge the two dimensions into a single dimension. Passing fewer_dims_optimization=false stops this optimization
9+ 
10+PiperOrigin-RevId: 384844496
11+Change-Id: Ifb02dc74964132c3ed3f3bc98b0858dbe4e258b7
12+---
13+ tensorflow/core/kernels/xent_op.cc | 23 +++++++------------
14+ .../python/kernel_tests/xent_op_test.py | 7 ++++++
15+ .../python/kernel_tests/xent_op_test_base.py | 3 +++
16+ 3 files changed, 18 insertions(+), 15 deletions(-)
17+ 
18+diff --git a/tensorflow/core/kernels/xent_op.cc b/tensorflow/core/kernels/xent_op.cc
19+index 2c252b5f21e296..7d8ad52c8958db 100644
20+--- a/tensorflow/core/kernels/xent_op.cc
21++++ b/tensorflow/core/kernels/xent_op.cc
22+@@ -46,7 +46,8 @@ class SoftmaxXentWithLogitsOp : public OpKernel {
23+ TensorShape shape_in = logits_in.shape();
24+
25+ BCast bcast(BCast::FromShape(logits_in.shape()),
26+- BCast::FromShape(labels_in.shape()));
27++ BCast::FromShape(labels_in.shape()),
28++ /*fewer_dims_optimization=*/false);
29+ if (!logits_in.IsSameSize(labels_in)) {
30+ OP_REQUIRES(context, bcast.IsValid(),
31+ errors::InvalidArgument(
32+@@ -88,20 +89,12 @@ class SoftmaxXentWithLogitsOp : public OpKernel {
33+ {0}, 1, shape_in, &back_out));
34+ if (shape_in.dim_size(0) > 0) {
35+ functor::XentFunctor<Device, T> functor;
36+- if (logits_in.IsSameSize(labels_in)) {
37+- functor(context->eigen_device<Device>(), shape_in.AsEigenDSizes<2>(),
38+- Eigen::array<Eigen::DenseIndex, 2>{1, 1},
39+- Eigen::array<Eigen::DenseIndex, 2>{1, 1}, logits_in.matrix<T>(),
40+- labels_in.matrix<T>(), scratch.matrix<T>(), loss_out->vec<T>(),
41+- back_out->matrix<T>());
42+- } else {
43+- functor(context->eigen_device<Device>(), shape_in.AsEigenDSizes<2>(),
44+- BCast::ToIndexArray<2>(bcast.x_bcast()),
45+- BCast::ToIndexArray<2>(bcast.y_bcast()),
46+- logits_in.template shaped<T, 2>(bcast.x_reshape()),
47+- labels_in.template shaped<T, 2>(bcast.y_reshape()),
48+- scratch.matrix<T>(), loss_out->vec<T>(), back_out->matrix<T>());
49+- }
50++ functor(context->eigen_device<Device>(), shape_in.AsEigenDSizes<2>(),
51++ BCast::ToIndexArray<2>(bcast.x_bcast()),
52++ BCast::ToIndexArray<2>(bcast.y_bcast()),
53++ logits_in.template shaped<T, 2>(bcast.x_reshape()),
54++ labels_in.template shaped<T, 2>(bcast.y_reshape()),
55++ scratch.matrix<T>(), loss_out->vec<T>(), back_out->matrix<T>());
56+ }
57+ }
58+ };
59+diff --git a/tensorflow/python/kernel_tests/xent_op_test.py b/tensorflow/python/kernel_tests/xent_op_test.py
60+index 9195619b161eed..24f38ed9d430b0 100644
61+--- a/tensorflow/python/kernel_tests/xent_op_test.py
62++++ b/tensorflow/python/kernel_tests/xent_op_test.py
63+@@ -63,6 +63,13 @@ def testFeaturesBroadcast(self):
64+ self.assertAllCloseAccordingToType(np_loss, tf_loss)
65+ self.assertAllCloseAccordingToType(np_gradient, tf_gradient)
66+
67++ tf_f = constant_op.constant(np.array([[1.]]).astype(np.float32))
68++ tf_l = constant_op.constant(np.array([[1.], [1.]]).astype(np.float32))
69++ tf_loss, tf_gradient = gen_nn_ops.softmax_cross_entropy_with_logits(
70++ tf_f, tf_l)
71++ self.assertAllClose([0, 0], tf_loss)
72++ self.assertAllCloseAccordingToType([[0], [0]], tf_gradient)
73++
74+ @test_util.run_deprecated_v1
75+ def testNotMatrix(self):
76+ with self.cached_session():
77+diff --git a/tensorflow/python/kernel_tests/xent_op_test_base.py b/tensorflow/python/kernel_tests/xent_op_test_base.py
78+index de464e9e277c25..0f7838c4260294 100644
79+--- a/tensorflow/python/kernel_tests/xent_op_test_base.py
80++++ b/tensorflow/python/kernel_tests/xent_op_test_base.py
81+@@ -151,6 +151,9 @@ def _testLabelsBroadcast(self, uniform_labels_gradient):
82+ labels = np.array([[0., 0., 0., 1.]]).astype(np.float16)
83+ logits = np.array([[1., 1., 1., 1.], [1., 2., 3., 4.]]).astype(np.float16)
84+ self._testXent2D(labels, logits, with_placeholders=True)
85++ labels = np.array([[1.]]).astype(np.float16)
86++ logits = np.array([[1.], [2.]]).astype(np.float16)
87++ self._testXent2D(labels, logits, with_placeholders=True)
88+ labels = np.array([[0.], [2.], [0.25]]).astype(np.float16)
89+ logits = np.array([[1., 1., 1., 1.], [1., 2., 3., 4.],
90+ [1., 2., 3., 4.]]).astype(np.float16)
@@ -0,0 +1,48 @@
1+From 4dddb2fd0b01cdd196101afbba6518658a2c9e07 Mon Sep 17 00:00:00 2001
2+From: Reed Wanderman-Milne <reedwm@google.com>
3+Date: Wed, 20 Oct 2021 14:53:58 -0700
4+Subject: [PATCH] Fix segfault in pools on empty shapes when certain dimension
5+ were very large.
6+ 
7+Pooling ops multiply certain components of the input shape, e.g. by multiplying input.shape[1] * input.shape[2] * input.shape[3]. This multiplication could overflow an int64 value if shape[0] was 0 but shape[1], shape[2], and shape[3] were very large, e.g. by passing an input with shape (0, 2**25, 2**25, 2**25).
8+ 
9+PiperOrigin-RevId: 404644978
10+Change-Id: Ic79f89c970357ca2962b1f231449066db9403146
11+---
12+ tensorflow/core/kernels/pooling_ops_common.h | 9 +++++++++
13+ 1 file changed, 9 insertions(+)
14+ 
15+diff --git a/tensorflow/core/kernels/pooling_ops_common.h b/tensorflow/core/kernels/pooling_ops_common.h
16+index 1a41a5adca5d29..8890e24a32ad97 100644
17+--- a/tensorflow/core/kernels/pooling_ops_common.h
18++++ b/tensorflow/core/kernels/pooling_ops_common.h
19+@@ -189,6 +189,9 @@ class MaxPoolingOp : public OpKernel {
20+ void SpatialMaxPool(OpKernelContext* context, Tensor* output,
21+ const Tensor& tensor_in, const PoolParameters& params,
22+ const Padding& padding) {
23++ if (output->NumElements() == 0) {
24++ return;
25++ }
26+ // On GPU, use Eigen's Spatial Max Pooling. On CPU, use an
27+ // EigenMatrix version that is currently faster than Eigen's
28+ // Spatial MaxPooling implementation.
29+@@ -443,6 +446,9 @@ class MaxPoolingV2Op : public OpKernel {
30+ void SpatialMaxPool(OpKernelContext* context, Tensor* output,
31+ const Tensor& tensor_in, const PoolParameters& params,
32+ const Padding& padding) {
33++ if (output->NumElements() == 0) {
34++ return;
35++ }
36+ // On GPU, use Eigen's Spatial Max Pooling. On CPU, use an
37+ // EigenMatrix version that is currently faster than Eigen's
38+ // Spatial MaxPooling implementation.
39+@@ -561,6 +567,9 @@ template <typename Device, typename T>
40+ void SpatialAvgPool(OpKernelContext* context, Tensor* output,
41+ const Tensor& input, const PoolParameters& params,
42+ const Padding& padding) {
43++ if (output->NumElements() == 0) {
44++ return;
45++ }
46+ typedef Eigen::Map<const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>
47+ ConstEigenMatrixMap;
48+ typedef Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>
@@ -0,0 +1,61 @@
1+From 579261dcd446385831fe4f7457d802a59685121d Mon Sep 17 00:00:00 2001
2+From: Reed Wanderman-Milne <reedwm@google.com>
3+Date: Wed, 14 Jul 2021 20:44:41 -0700
4+Subject: [PATCH] Fix crash in MatrixSolve when inputs have different batch
5+ dimensions.
6+ 
7+Before, the process would crash or certain elements would be silently ignored. Now an InvalidArgument is raised.
8+ 
9+PiperOrigin-RevId: 384844020
10+Change-Id: Iba44417e383bdd0e1abc4012bfca83b2377dd335
11+---
12+ tensorflow/core/kernels/linalg/matrix_solve_op.cc | 11 +++++++++--
13+ .../python/kernel_tests/matrix_solve_op_test.py | 6 ++++++
14+ 2 files changed, 15 insertions(+), 2 deletions(-)
15+ 
16+diff --git a/tensorflow/core/kernels/linalg/matrix_solve_op.cc b/tensorflow/core/kernels/linalg/matrix_solve_op.cc
17+index 70f02bddf9b785..aeb0203b4a337d 100644
18+--- a/tensorflow/core/kernels/linalg/matrix_solve_op.cc
19++++ b/tensorflow/core/kernels/linalg/matrix_solve_op.cc
20+@@ -143,15 +143,22 @@ class MatrixSolveOpGpu : public AsyncOpKernel {
21+ done);
22+ OP_REQUIRES_ASYNC(
23+ context, input.dim_size(ndims - 2) == n,
24+- errors::InvalidArgument("Input matrices must be squares, got",
25++ errors::InvalidArgument("Input matrices must be squares, got ",
26+ input.dim_size(ndims - 2), " != ", n),
27+ done);
28+ OP_REQUIRES_ASYNC(context, rhs.dim_size(ndims - 2) == n,
29+ errors::InvalidArgument(
30+ "Input matrix and right-hand side must have the "
31+- "same number of rows, got",
32++ "same number of rows, got ",
33+ n, " != ", rhs.dim_size(ndims - 2)),
34+ done);
35++ for (int dim = 0; dim < ndims - 2; dim++) {
36++ OP_REQUIRES_ASYNC(
37++ context, input.dim_size(dim) == rhs.dim_size(dim),
38++ errors::InvalidArgument(
39++ "All input tensors must have the same outer dimensions."),
40++ done);
41++ }
42+
43+ // Allocate output.
44+ Tensor* output;
45+diff --git a/tensorflow/python/kernel_tests/matrix_solve_op_test.py b/tensorflow/python/kernel_tests/matrix_solve_op_test.py
46+index 0d149de2acb5e5..1739b2272be810 100644
47+--- a/tensorflow/python/kernel_tests/matrix_solve_op_test.py
48++++ b/tensorflow/python/kernel_tests/matrix_solve_op_test.py
49+@@ -112,6 +112,12 @@ def testWrongDimensions(self):
50+ with self.assertRaises((ValueError, errors_impl.InvalidArgumentError)):
51+ self.evaluate(linalg_ops.matrix_solve(matrix, rhs))
52+
53++ # The matrix and right-hand side should have the same batch dimensions
54++ matrix = np.random.normal(size=(2, 6, 2, 2))
55++ rhs = np.random.normal(size=(2, 3, 2, 2))
56++ with self.assertRaises((ValueError, errors_impl.InvalidArgumentError)):
57++ self.evaluate(linalg_ops.matrix_solve(matrix, rhs))
58++
59+ def testNotInvertible(self):
60+ # The input should be invertible.
61+ with self.assertRaisesOpError("Input matrix is not invertible."):
@@ -0,0 +1,129 @@
1+From 68422b215e618df5ad375bcdc6d2052e9fd3080a Mon Sep 17 00:00:00 2001
2+From: Reed Wanderman-Milne <reedwm@google.com>
3+Date: Fri, 8 Oct 2021 08:21:33 -0700
4+Subject: [PATCH] Add shape checks to GPU TridiagonalMatMul.
5+ 
6+When given invalid shapes, the GPU TridiagonalMatMul op could read invalid or uninitialized GPU memory.
7+ 
8+PiperOrigin-RevId: 401775483
9+Change-Id: Ib5500aeb8225e50d4ce790b06d2c34751f544ad8
10+---
11+ .../linalg/tridiagonal_matmul_op_gpu.cu.cc | 39 +++++++++++++++++++
12+ .../tridiagonal_matmul_op_test.py | 34 ++++++++++++++++
13+ 2 files changed, 73 insertions(+)
14+ 
15+diff --git a/tensorflow/core/kernels/linalg/tridiagonal_matmul_op_gpu.cu.cc b/tensorflow/core/kernels/linalg/tridiagonal_matmul_op_gpu.cu.cc
16+index a1fe54e073b1b5..c1b75f2cd0e3cb 100644
17+--- a/tensorflow/core/kernels/linalg/tridiagonal_matmul_op_gpu.cu.cc
18++++ b/tensorflow/core/kernels/linalg/tridiagonal_matmul_op_gpu.cu.cc
19+@@ -66,6 +66,12 @@ class TridiagonalMatMulOpGpu : public OpKernel {
20+ const Tensor& rhs = context->input(3);
21+
22+ const int ndims = rhs.dims();
23++ OP_REQUIRES(
24++ context, ndims >= 2,
25++ errors::InvalidArgument("Input must have rank >= 2, but got ", ndims));
26++ OP_REQUIRES_OK(context, ValidateInputTensor(superdiag, "superdiag", rhs));
27++ OP_REQUIRES_OK(context, ValidateInputTensor(maindiag, "maindiag", rhs));
28++ OP_REQUIRES_OK(context, ValidateInputTensor(subdiag, "subdiag", rhs));
29+ int64 batch_size = 1;
30+ for (int i = 0; i < ndims - 2; i++) {
31+ batch_size *= rhs.dim_size(i);
32+@@ -85,6 +91,39 @@ class TridiagonalMatMulOpGpu : public OpKernel {
33+ maindiag.flat<Scalar>().data(), subdiag.flat<Scalar>().data(),
34+ rhs.flat<Scalar>().data(), output->flat<Scalar>().data()));
35+ }
36++
37++ private:
38++ Status ValidateInputTensor(const Tensor& tensor,
39++ const std::string& tensor_name,
40++ const Tensor& rhs) {
41++ const int ndims = rhs.dims();
42++ if (tensor.dims() != ndims) {
43++ return errors::InvalidArgument(tensor_name,
44++ " must have same rank as rhs, but got ",
45++ tensor.dims(), " and ", ndims);
46++ }
47++ for (int i = 0; i < ndims - 2; i++) {
48++ if (tensor.dim_size(i) != rhs.dim_size(i)) {
49++ return errors::InvalidArgument(
50++ tensor_name,
51++ " must have same outer dimensions as rhs, but for index ", i,
52++ ", got ", tensor.dim_size(i), " and ", rhs.dim_size(i));
53++ }
54++ }
55++ if (tensor.dim_size(ndims - 2) != 1) {
56++ return errors::InvalidArgument(
57++ tensor_name, "'s second-to-last dimension must be 1, but got ",
58++ tensor.dim_size(ndims - 2));
59++ }
60++ if (tensor.dim_size(ndims - 1) != rhs.dim_size(ndims - 2)) {
61++ return errors::InvalidArgument(tensor_name,
62++ "'s last dimension size must be rhs's "
63++ "second-to-last dimension size, but got ",
64++ tensor.dim_size(ndims - 1), " and ",
65++ rhs.dim_size(ndims - 2));
66++ }
67++ return Status::OK();
68++ }
69+ };
70+
71+ REGISTER_LINALG_OP_GPU("TridiagonalMatMul", (TridiagonalMatMulOpGpu<float>),
72+diff --git a/tensorflow/python/kernel_tests/tridiagonal_matmul_op_test.py b/tensorflow/python/kernel_tests/tridiagonal_matmul_op_test.py
73+index 3fd04bf19114fc..3bca2a39f08b0b 100644
74+--- a/tensorflow/python/kernel_tests/tridiagonal_matmul_op_test.py
75++++ b/tensorflow/python/kernel_tests/tridiagonal_matmul_op_test.py
76+@@ -19,12 +19,15 @@
77+ import numpy as np
78+
79+ from tensorflow.python.client import session
80++from tensorflow.python.eager import context
81+ from tensorflow.python.framework import constant_op
82+ from tensorflow.python.framework import dtypes
83++from tensorflow.python.framework import errors_impl
84+ from tensorflow.python.framework import ops
85+ from tensorflow.python.ops import array_ops
86+ from tensorflow.python.ops import control_flow_ops
87+ from tensorflow.python.ops import gradient_checker_v2
88++from tensorflow.python.ops import linalg_ops
89+ from tensorflow.python.ops import math_ops
90+ from tensorflow.python.ops import variables
91+ from tensorflow.python.ops.linalg import linalg_impl
92+@@ -175,6 +178,37 @@ def testGradientComplexWithBatches(self):
93+ rhs = self._randomComplexArray((b, m, n))
94+ self._gradientTest(diags, rhs, dtype=dtypes.complex128)
95+
96++ def _testErrorWithShapesEager(self, exception_regex, superdiag_shape,
97++ maindiag_shape, subdiag_shape, rhs_shape):
98++ with context.eager_mode():
99++ superdiag = array_ops.ones(superdiag_shape)
100++ maindiag = array_ops.ones(maindiag_shape)
101++ subdiag = array_ops.ones(subdiag_shape)
102++ rhs = array_ops.ones(rhs_shape)
103++ with self.assertRaisesRegex(errors_impl.InvalidArgumentError,
104++ exception_regex):
105++ linalg_ops.tridiagonal_mat_mul(superdiag, maindiag, subdiag, rhs)
106++
107++ def testInvalidShapesEagerGpu(self):
108++ if not test.is_gpu_available():
109++ self.skipTest('Test requires GPU')
110++ self._testErrorWithShapesEager('Input must have rank >= 2, but got ',
111++ [2], [2], [2], [2])
112++ self._testErrorWithShapesEager(
113++ 'superdiag must have same rank as rhs, but got 3 and 2',
114++ [2, 1, 2], [2, 1], [2, 1], [2, 2])
115++ self._testErrorWithShapesEager(
116++ 'maindiag must have same outer dimensions as rhs, but for index 0, got '
117++ '3 and 2',
118++ [2, 1, 2], [3, 1, 2], [2, 1, 2], [2, 2, 2])
119++ self._testErrorWithShapesEager(
120++ "subdiag's second-to-last dimension must be 1, but got 3",
121++ [2, 1, 2], [2, 1, 2], [2, 3, 2], [2, 2, 2])
122++ self._testErrorWithShapesEager(
123++ "subdiag's last dimension size must be rhs's second-to-last dimension "
124++ "size, but got 3 and 2",
125++ [2, 1, 2], [2, 1, 2], [2, 1, 3], [2, 2, 2])
126++
127+ # Benchmark
128+ class TridiagonalMatMulBenchmark(test.Benchmark):
129+ sizes = [(100000, 1, 1), (1000000, 1, 1), (10000000, 1, 1), (100000, 10, 1),
@@ -0,0 +1,337 @@
1+From da4aad5946be30e5f049920fa076e1f7ef021261 Mon Sep 17 00:00:00 2001
2+From: Reed Wanderman-Milne <reedwm@google.com>
3+Date: Fri, 8 Oct 2021 20:24:45 -0700
4+Subject: [PATCH] Roll forward
5+ https://github.com/tensorflow/tensorflow/commit/ab0ca4bbc66a476aea305f81c69e0201b5876d0a.
6+ The internal test that it broke has been fixed.
7+ 
8+PiperOrigin-RevId: 401913101
9+Change-Id: I67f095899187e38101fbb10289c5e444b0a9e8c0
10+---
11+ tensorflow/core/kernels/maxpooling_op.cc | 47 +++++++++++
12+ tensorflow/core/kernels/pooling_ops_3d.cc | 21 +++++
13+ tensorflow/core/kernels/pooling_ops_common.cc | 10 +++
14+ tensorflow/core/kernels/pooling_ops_common.h | 5 --
15+ .../kernel_tests/pooling_ops_3d_test.py | 42 ++++++++++
16+ .../python/kernel_tests/pooling_ops_test.py | 77 +++++++++++++++++++
17+ 6 files changed, 197 insertions(+), 5 deletions(-)
18+ 
19+diff --git a/tensorflow/core/kernels/maxpooling_op.cc b/tensorflow/core/kernels/maxpooling_op.cc
20+index ce89b025ec558f..9edd5cf6a6d52b 100644
21+--- a/tensorflow/core/kernels/maxpooling_op.cc
22++++ b/tensorflow/core/kernels/maxpooling_op.cc
23+@@ -325,6 +325,14 @@ class MaxPoolingGradOp : public OpKernel {
24+ if (!context->status().ok()) {
25+ return;
26+ }
27++ OP_REQUIRES(context, tensor_out.shape() == params.forward_output_shape(),
28++ errors::InvalidArgument("Expected orig_output shape to be ",
29++ params.forward_output_shape(),
30++ ", but got ", tensor_out.shape()));
31++ OP_REQUIRES(context, out_backprop.shape() == params.forward_output_shape(),
32++ errors::InvalidArgument("Expected grad shape to be ",
33++ params.forward_output_shape(),
34++ ", but got ", out_backprop.shape()));
35+
36+ Tensor* output = nullptr;
37+ OP_REQUIRES_OK(context, context->forward_input_or_allocate_output(
38+@@ -538,6 +546,18 @@ class MaxPoolingGradGradOp : public OpKernel {
39+ /*explicit_paddings=*/{},
40+ FORMAT_NHWC,
41+ tensor_in.shape()};
42++ if (!context->status().ok()) {
43++ return;
44++ }
45++ OP_REQUIRES(context, tensor_out.shape() == params.forward_output_shape(),
46++ errors::InvalidArgument("Expected orig_output shape to be ",
47++ params.forward_output_shape(),
48++ ", but got ", tensor_out.shape()));
49++ OP_REQUIRES(
50++ context, out_grad_backprop.shape() == tensor_in.shape(),
51++ errors::InvalidArgument("Expected grad shape to be ", tensor_in.shape(),
52++ ", but got ", out_grad_backprop.shape()));
53++
54+ Tensor* output = nullptr;
55+ OP_REQUIRES_OK(context, context->forward_input_or_allocate_output(
56+ {2}, 0, tensor_out.shape(), &output));
57+@@ -742,6 +762,17 @@ class MaxPoolingGradGradOp<Eigen::GpuDevice, T> : public OpKernel {
58+ /*explicit_paddings=*/{},
59+ data_format_,
60+ tensor_in.shape()};
61++ if (!context->status().ok()) {
62++ return;
63++ }
64++ OP_REQUIRES(context, tensor_out.shape() == params.forward_output_shape(),
65++ errors::InvalidArgument("Expected orig_output shape to be ",
66++ params.forward_output_shape(),
67++ ", but got ", tensor_out.shape()));
68++ OP_REQUIRES(
69++ context, out_grad_backprop.shape() == tensor_in.shape(),
70++ errors::InvalidArgument("Expected grad shape to be ", tensor_in.shape(),
71++ ", but got ", out_grad_backprop.shape()));
72+
73+ functor::MaxPoolGradBackwardNoMask<T>()(
74+ data_format_, tensor_in.flat<T>().data(), tensor_out.flat<T>().data(),
75+@@ -1096,6 +1127,14 @@ class MaxPoolingGradWithArgmaxOp : public OpKernel {
76+ if (!context->status().ok()) {
77+ return;
78+ }
79++ OP_REQUIRES(context, grad_in.shape() == params.forward_output_shape(),
80++ errors::InvalidArgument("Expected grad shape to be ",
81++ params.forward_output_shape(),
82++ ", but got ", grad_in.shape()));
83++ OP_REQUIRES(context, argmax.shape() == params.forward_output_shape(),
84++ errors::InvalidArgument("Expected argmax shape to be ",
85++ params.forward_output_shape(),
86++ ", but got ", argmax.shape()));
87+
88+ TensorShape out_shape({params.tensor_in_batch, params.tensor_in_rows,
89+ params.tensor_in_cols, params.depth});
90+@@ -1156,6 +1195,14 @@ class MaxPoolingGradGradWithArgmaxOp : public OpKernel {
91+ if (!context->status().ok()) {
92+ return;
93+ }
94++ OP_REQUIRES(
95++ context, grad_in.shape() == tensor_in.shape(),
96++ errors::InvalidArgument("Expected grad shape to be ", tensor_in.shape(),
97++ ", but got ", grad_in.shape()));
98++ OP_REQUIRES(context, argmax.shape() == params.forward_output_shape(),
99++ errors::InvalidArgument("Expected argmax shape to be ",
100++ params.forward_output_shape(),
101++ ", but got ", argmax.shape()));
102+
103+ TensorShape out_shape({params.tensor_in_batch, params.out_height,
104+ params.out_width, params.depth});
105+diff --git a/tensorflow/core/kernels/pooling_ops_3d.cc b/tensorflow/core/kernels/pooling_ops_3d.cc
106+index d4dc87c7e3f86f..d4444b677a9504 100644
107+--- a/tensorflow/core/kernels/pooling_ops_3d.cc
108++++ b/tensorflow/core/kernels/pooling_ops_3d.cc
109+@@ -366,6 +366,19 @@ class MaxPooling3dGradOp : public OpKernel {
110+
111+ OP_REQUIRES_OK(context, Get3dOutputSize(input_size, window, stride,
112+ padding_, &out, &padding));
113++
114++ const int64_t depth = GetTensorDim(tensor_in, data_format_, 'C');
115++ const int64_t in_batch = GetTensorDim(tensor_in, data_format_, 'N');
116++ TensorShape out_shape = ShapeFromFormat(data_format_, in_batch,
117++ {{out[2], out[1], out[0]}}, depth);
118++ OP_REQUIRES(
119++ context, tensor_out.shape() == out_shape,
120++ errors::InvalidArgument("Expected orig_output shape to be ", out_shape,
121++ ", but got ", tensor_out.shape()));
122++ OP_REQUIRES(context, out_backprop.shape() == out_shape,
123++ errors::InvalidArgument("Expected grad shape to be ", out_shape,
124++ ", but got ", out_backprop.shape()));
125++
126+ LaunchMaxPooling3dGradOp<Device, T>::launch(
127+ context, tensor_in, tensor_out, out_backprop, window, stride, out,
128+ padding, data_format_, input_backprop);
129+@@ -712,6 +725,14 @@ class MaxPooling3dGradGradOp : public OpKernel {
130+ Pool3dParameters params{context, ksize_, stride_,
131+ padding_, data_format_, tensor_in.shape()};
132+ if (!context->status().ok()) return; // params is invalid
133++ OP_REQUIRES(context, tensor_out.shape() == params.forward_output_shape(),
134++ errors::InvalidArgument("Expected orig_output shape to be ",
135++ params.forward_output_shape(),
136++ ", but got ", tensor_out.shape()));
137++ OP_REQUIRES(
138++ context, out_grad_backprop.shape() == tensor_in.shape(),
139++ errors::InvalidArgument("Expected grad shape to be ", tensor_in.shape(),
140++ ", but got ", out_grad_backprop.shape()));
141+
142+ Tensor* output = nullptr;
143+ OP_REQUIRES_OK(context, context->forward_input_or_allocate_output(
144+diff --git a/tensorflow/core/kernels/pooling_ops_common.cc b/tensorflow/core/kernels/pooling_ops_common.cc
145+index 817072cc7617d4..d621e77790c626 100644
146+--- a/tensorflow/core/kernels/pooling_ops_common.cc
147++++ b/tensorflow/core/kernels/pooling_ops_common.cc
148+@@ -465,6 +465,16 @@ void DnnPoolingGradOp<T>::Compute(
149+ if (!context->status().ok()) {
150+ return;
151+ }
152++ if (tensor_out) {
153++ OP_REQUIRES(context, tensor_out->shape() == params.forward_output_shape(),
154++ errors::InvalidArgument("Expected orig_output shape to be ",
155++ params.forward_output_shape(),
156++ ", but got ", tensor_out->shape()));
157++ }
158++ OP_REQUIRES(context, out_backprop.shape() == params.forward_output_shape(),
159++ errors::InvalidArgument("Expected grad shape to be ",
160++ params.forward_output_shape(),
161++ ", but got ", out_backprop.shape()));
162+
163+ TensorFormat transformed_input_data_format = data_format;
164+
165+diff --git a/tensorflow/core/kernels/pooling_ops_common.h b/tensorflow/core/kernels/pooling_ops_common.h
166+index 5e6f2e46944a98..1a41a5adca5d29 100644
167+--- a/tensorflow/core/kernels/pooling_ops_common.h
168++++ b/tensorflow/core/kernels/pooling_ops_common.h
169+@@ -83,11 +83,6 @@ struct PoolParameters {
170+ TensorFormat data_format;
171+ };
172+
173+-// Checks if the sizes of the paddings are less than the size of window.
174+-// This is required for MaxPool because it pads with -inf, so the pooling
175+-// window cannot fully cover the padded area.
176+-Status CheckPaddingSize(PoolParameters& params);
177+-
178+ // An implementation of MaxPooling (forward).
179+ // TODO (yongtang): Remove MaxPoolingOp and use MaxPoolingV2Op,
180+ // QuantizedMaxPoolingOp depends on MaxPoolingOp so keep intact for now
181+diff --git a/tensorflow/python/kernel_tests/pooling_ops_3d_test.py b/tensorflow/python/kernel_tests/pooling_ops_3d_test.py
182+index 203d3ad2f280fb..12710c47a4a3dd 100644
183+--- a/tensorflow/python/kernel_tests/pooling_ops_3d_test.py
184++++ b/tensorflow/python/kernel_tests/pooling_ops_3d_test.py
185+@@ -16,9 +16,13 @@
186+
187+ import numpy as np
188+
189++from tensorflow.python.eager import context
190+ from tensorflow.python.framework import constant_op
191+ from tensorflow.python.framework import errors
192++from tensorflow.python.framework import errors_impl
193+ from tensorflow.python.framework import test_util
194++from tensorflow.python.ops import array_ops
195++from tensorflow.python.ops import gen_nn_ops
196+ from tensorflow.python.ops import gradient_checker
197+ from tensorflow.python.ops import gradients_impl
198+ from tensorflow.python.ops import nn_ops
199+@@ -515,6 +519,44 @@ def testMaxPool3DZeroPoolSize(self):
200+ pool_3d = f(input_tensor, ksize=[2, 2, 0], strides=1, padding="VALID")
201+ self.evaluate(pool_3d)
202+
203++ def testMaxPoolGradEagerShapeErrors(self):
204++ with context.eager_mode():
205++ orig_in = array_ops.ones((1, 1, 1, 1, 1))
206++
207++ # Test invalid orig_out shape
208++ orig_out = array_ops.ones((1, 1, 1, 1, 2))
209++ grad = array_ops.ones((1, 1, 1, 1, 1))
210++ with self.assertRaisesRegex(
211++ errors_impl.InvalidArgumentError,
212++ r"Expected orig_output shape to be \[1,1,1,1,1\], but got "
213++ r"\[1,1,1,1,2\]"):
214++ gen_nn_ops.max_pool3d_grad(
215++ orig_in, orig_out, grad, ksize=[1, 1, 1, 1, 1],
216++ strides=[1, 1, 1, 1, 1], padding="VALID")
217++ with self.assertRaisesRegex(
218++ errors_impl.InvalidArgumentError,
219++ r"Expected orig_output shape to be \[1,1,1,1,1\], but got "
220++ r"\[1,1,1,1,2\]"):
221++ gen_nn_ops.max_pool3d_grad_grad(
222++ orig_in, orig_out, grad, ksize=[1, 1, 1, 1, 1],
223++ strides=[1, 1, 1, 1, 1], padding="VALID")
224++
225++ # Test invalid grad shape
226++ orig_out = array_ops.ones((1, 1, 1, 1, 1))
227++ grad = array_ops.ones((1, 1, 1, 1, 2))
228++ with self.assertRaisesRegex(
229++ errors_impl.InvalidArgumentError,
230++ r"Expected grad shape to be \[1,1,1,1,1\], but got \[1,1,1,1,2\]"):
231++ gen_nn_ops.max_pool3d_grad(
232++ orig_in, orig_out, grad, ksize=[1, 1, 1, 1, 1],
233++ strides=[1, 1, 1, 1, 1], padding="VALID")
234++ with self.assertRaisesRegex(
235++ errors_impl.InvalidArgumentError,
236++ r"Expected grad shape to be \[1,1,1,1,1\], but got \[1,1,1,1,2\]"):
237++ gen_nn_ops.max_pool3d_grad_grad(
238++ orig_in, orig_out, grad, ksize=[1, 1, 1, 1, 1],
239++ strides=[1, 1, 1, 1, 1], padding="VALID")
240++
241+
242+ if __name__ == "__main__":
243+ test.main()
244+diff --git a/tensorflow/python/kernel_tests/pooling_ops_test.py b/tensorflow/python/kernel_tests/pooling_ops_test.py
245+index 6f1b5ede1f3ad8..79adfff643fd9d 100644
246+--- a/tensorflow/python/kernel_tests/pooling_ops_test.py
247++++ b/tensorflow/python/kernel_tests/pooling_ops_test.py
248+@@ -618,6 +618,7 @@ def testMaxPoolExplicitPaddingAdvanced(self, **kwargs):
249+
250+ @parameterized.parameters(
251+ GetTestConfigsDicts(nn_ops.max_pool, nn_ops.max_pool_v2))
252++ @test_util.xla_allow_fallback("XLA doesn't support explicit padding")
253+ @test_util.run_deprecated_v1
254+ def testMaxPoolNegativeInputExpPaddingAdv(self, **kwargs):
255+ expected_output = [-1, -1, -3, -5, -7, -7, -9, -11, -19, -19, -21, -23, -31,
256+@@ -2390,6 +2391,82 @@ def testExplicitPaddingBatch(self):
257+ explicit_paddings=[1, 1, 1, 1, 1, 1, 0, 0],
258+ data_format="NHWC"))
259+
260++ def testMaxPoolGradEagerShapeErrors(self):
261++ with context.eager_mode():
262++ orig_in = array_ops.ones((1, 1, 1, 1))
263++
264++ # Test invalid orig_out shape
265++ orig_out = array_ops.ones((1, 1, 1, 2))
266++ grad = array_ops.ones((1, 1, 1, 1))
267++ with self.assertRaisesRegex(
268++ errors_impl.InvalidArgumentError,
269++ r"Expected orig_output shape to be \[1,1,1,1\], but got \[1,1,1,2\]"):
270++ gen_nn_ops.max_pool_grad(
271++ orig_in, orig_out, grad, ksize=[1, 1, 1, 1], strides=[1, 1, 1, 1],
272++ padding="VALID")
273++ with self.assertRaisesRegex(
274++ errors_impl.InvalidArgumentError,
275++ r"Expected orig_output shape to be \[1,1,1,1\], but got \[1,1,1,2\]"):
276++ gen_nn_ops.max_pool_grad_grad(
277++ orig_in, orig_out, grad, ksize=[1, 1, 1, 1], strides=[1, 1, 1, 1],
278++ padding="VALID")
279++
280++ # Test invalid grad shape
281++ orig_out = array_ops.ones((1, 1, 1, 1))
282++ grad = array_ops.ones((1, 1, 1, 2))
283++ with self.assertRaisesRegex(
284++ errors_impl.InvalidArgumentError,
285++ r"Expected grad shape to be \[1,1,1,1\], but got \[1,1,1,2\]"):
286++ gen_nn_ops.max_pool_grad(
287++ orig_in, orig_out, grad, ksize=[1, 1, 1, 1], strides=[1, 1, 1, 1],
288++ padding="VALID")
289++ with self.assertRaisesRegex(
290++ errors_impl.InvalidArgumentError,
291++ r"Expected grad shape to be \[1,1,1,1\], but got \[1,1,1,2\]"):
292++ gen_nn_ops.max_pool_grad_grad(
293++ orig_in, orig_out, grad, ksize=[1, 1, 1, 1], strides=[1, 1, 1, 1],
294++ padding="VALID")
295++
296++ def testMaxPoolGradWithArgmaxEagerShapeErrors(self):
297++ with context.eager_mode():
298++ inp = array_ops.ones((1, 1, 1, 1))
299++
300++ # Test invalid grad shape
301++ grad = array_ops.ones((1, 1, 1, 2))
302++ argmax = array_ops.zeros((1, 1, 1, 1), dtype=dtypes.int64)
303++ with self.assertRaisesRegex(
304++ errors_impl.InvalidArgumentError,
305++ r"Expected grad shape to be \[1,1,1,1\], but got \[1,1,1,2\]"):
306++ gen_nn_ops.max_pool_grad_with_argmax(
307++ inp, grad, argmax, ksize=[1, 1, 1, 1], strides=[1, 1, 1, 1],
308++ padding="VALID")
309++ # max_pool_grad_grad_with_argmax is only implemented for GPUs
310++ if test.is_gpu_available():
311++ with self.assertRaisesRegex(
312++ errors_impl.InvalidArgumentError,
313++ r"Expected grad shape to be \[1,1,1,1\], but got \[1,1,1,2\]"):
314++ gen_nn_ops.max_pool_grad_grad_with_argmax(
315++ inp, grad, argmax, ksize=[1, 1, 1, 1], strides=[1, 1, 1, 1],
316++ padding="VALID")
317++
318++ # Test invalid argmax shape
319++ grad = array_ops.ones((1, 1, 1, 1))
320++ argmax = array_ops.ones((1, 1, 1, 2), dtype=dtypes.int64)
321++ with self.assertRaisesRegex(
322++ errors_impl.InvalidArgumentError,
323++ r"Expected argmax shape to be \[1,1,1,1\], but got \[1,1,1,2\]"):
324++ gen_nn_ops.max_pool_grad_with_argmax(
325++ inp, grad, argmax, ksize=[1, 1, 1, 1], strides=[1, 1, 1, 1],
326++ padding="VALID")
327++ # max_pool_grad_grad_with_argmax is only implemented for GPUs
328++ if test.is_gpu_available():
329++ with self.assertRaisesRegex(
330++ errors_impl.InvalidArgumentError,
331++ r"Expected argmax shape to be \[1,1,1,1\], but got \[1,1,1,2\]"):
332++ gen_nn_ops.max_pool_grad_grad_with_argmax(
333++ inp, grad, argmax, ksize=[1, 1, 1, 1], strides=[1, 1, 1, 1],
334++ padding="VALID")
335++
336+
337+ def GetMaxPoolFwdTest(input_size, filter_size, strides, padding):
@@ -0,0 +1,48 @@
1+From e7f497570abb6b4ae5af4970620cd880e4c0c904 Mon Sep 17 00:00:00 2001
2+From: Reed Wanderman-Milne <reedwm@google.com>
3+Date: Wed, 20 Oct 2021 15:41:05 -0700
4+Subject: [PATCH] Fix segfault on OOM in Conv2D.
5+ 
6+PiperOrigin-RevId: 404655317
7+Change-Id: I33588dbd3f5d0fef980e3c908bf5515a9ee09ce7
8+---
9+ tensorflow/core/kernels/conv_ops.cc | 15 ++++++++++++---
10+ 1 file changed, 12 insertions(+), 3 deletions(-)
11+ 
12+diff --git a/tensorflow/core/kernels/conv_ops.cc b/tensorflow/core/kernels/conv_ops.cc
13+index 94926358675fb2..67418151a1cf2d 100644
14+--- a/tensorflow/core/kernels/conv_ops.cc
15++++ b/tensorflow/core/kernels/conv_ops.cc
16+@@ -183,12 +183,18 @@ struct LaunchGrouped {
17+ auto on_shuffled = [&]() { shuffles_completed.DecrementCount(); };
18+
19+ // Shuffle input into temporary tensor.
20+- Tensor input_shuffled(input.dtype(), TensorShape(post_shuffle(input)));
21++ Tensor input_shuffled;
22++ OP_REQUIRES_OK(
23++ ctx, ctx->allocate_temp(input.dtype(), TensorShape(post_shuffle(input)),
24++ &input_shuffled));
25+ input_shuffled.tensor<T, 5>().device(device, on_shuffled) =
26+ input.shaped<T, 5>(pre_shuffle(input)).shuffle(shuffle);
27+
28+ // Shuffle filter into temporary tensor.
29+- Tensor filter_shuffled(filter.dtype(), TensorShape(post_shuffle(filter)));
30++ Tensor filter_shuffled;
31++ OP_REQUIRES_OK(ctx, ctx->allocate_temp(filter.dtype(),
32++ TensorShape(post_shuffle(filter)),
33++ &filter_shuffled));
34+ filter_shuffled.tensor<T, 5>().device(device, on_shuffled) =
35+ filter.shaped<T, 5>(pre_shuffle(filter)).shuffle(shuffle);
36+
37+@@ -196,7 +202,10 @@ struct LaunchGrouped {
38+ shuffles_completed.Wait();
39+
40+ // Write group convolution results into temporary output tensor.
41+- Tensor output_shuffled(output->dtype(), TensorShape(post_shuffle(*output)));
42++ Tensor output_shuffled;
43++ OP_REQUIRES_OK(ctx, ctx->allocate_temp(output->dtype(),
44++ TensorShape(post_shuffle(*output)),
45++ &output_shuffled));
46+
47+ for (int64_t i = 0; i < num_groups; ++i) {
48+ // TODO(ezhulenev): Run this loop using `parallelFor` (regular parallelFor
@@ -1,7 +1,7 @@
1%global _empty_manifest_terminate_build 01%global _empty_manifest_terminate_build 0
2Name: tensorflow2Name: tensorflow
3Version: 2.12.13Version: 2.12.1
4-Release: 54+Release: 6
5Summary: An Open Source Machine Learning Framework for Everyone5Summary: An Open Source Machine Learning Framework for Everyone
6License: Apache License 2.06License: Apache License 2.0
7URL: https://www.tensorflow.org/7URL: https://www.tensorflow.org/
@@ -17,6 +17,12 @@ Patch1000: aarch64_external_files.patch
17%endif17%endif
18%ifarch riscv6418%ifarch riscv64
19Patch1100: riscv64_external_files.patch19Patch1100: riscv64_external_files.patch
20+Patch1101: backport-CVE-2021-41206-1.patch
21+Patch1102: backport-CVE-2021-41206-2.patch
22+Patch1103: backport-CVE-2021-41206-3.patch
23+Patch1104: backport-CVE-2021-41206-4.patch
24+Patch1105: backport-CVE-2021-41206-5.patch
25+Patch1106: backport-CVE-2021-41206-6.patch
20%endif26%endif
21Requires: python3-future python3-numpy python3-six python3-astunparse python3-google-pasta python3-opt-einsum27Requires: python3-future python3-numpy python3-six python3-astunparse python3-google-pasta python3-opt-einsum
22Requires: python3-typing-extensions python3-wrapt python3-h5py python3-protobuf python3-grpcio python3-absl-py 28Requires: python3-typing-extensions python3-wrapt python3-h5py python3-protobuf python3-grpcio python3-absl-py
@@ -45,6 +51,12 @@ TensorFlow provides stable Python and C++ APIs, as well as non-guaranteed backwa
45 51 
46%prep52%prep
47%setup -n %{name}-%{version}53%setup -n %{name}-%{version}
54+%patch -P 1101 -p1
55+%patch -P 1102 -p1
56+%patch -P 1103 -p1
57+%patch -P 1104 -p1
58+%patch -P 1105 -p1
59+%patch -P 1106 -p1
48%patch 0 -p160%patch 0 -p1
49%patch 1 -p161%patch 1 -p1
50%patch 2 -p162%patch 2 -p1
@@ -84,6 +96,8 @@ bazel --output_user_root=`pwd`/../output_user_root build --nofetch --host_copt=-
84%{_bindir}/*96%{_bindir}/*
85 97 
86%changelog98%changelog
99+* Tue Jun 02 2026 sunwenhan <sunwenhan@xfusion.com> - 2.12.1-6
100+- Fix CVE-2021-41206
87* Tue Mar 03 2026 megranate wangkunjie@xfuison.com - 2.12.1-5101* Tue Mar 03 2026 megranate wangkunjie@xfuison.com - 2.12.1-5
88- fix CVE-2026-2492102- fix CVE-2026-2492
89 103 
@@ -122,4 +136,4 @@ bazel --output_user_root=`pwd`/../output_user_root build --nofetch --host_copt=-
122- fix some cves136- fix some cves
123 137 
124* Wed Sep 30 2020 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.3.1-1138* Wed Sep 30 2020 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.3.1-1
125-- Package init139+- Package init