Skip to content

Commit 959bf5a

Browse files
[AUTO-CHERRYPICK] Add patch for CVE-2023-33976 in tensorflow - branch main (#10213)
Co-authored-by: aadhar-agarwal <108542189+aadhar-agarwal@users.noreply.github.com>
1 parent 529c4fe commit 959bf5a

2 files changed

Lines changed: 182 additions & 1 deletion

File tree

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
From 915884fdf5df34aaedd00fc6ace33a2cfdefa586 Mon Sep 17 00:00:00 2001
2+
From: Cesar Crusius <ccrusius@google.com>
3+
Date: Mon, 27 Feb 2023 10:14:05 -0800
4+
Subject: [PATCH] Check for correct `values` rank in UpperBound and LowerBound.
5+
6+
The shape function in array_ops.cc for those ops requires that
7+
argument to have rank 2, but that function is bypassed when switching
8+
between graph and eager modes, allowing for invalid arguments to
9+
pass through and, in the test case, cause a segfault.
10+
11+
PiperOrigin-RevId: 512661338
12+
---
13+
tensorflow/core/kernels/searchsorted_op.cc | 32 ++++++++++---
14+
tensorflow/python/ops/array_ops_test.py | 54 ++++++++++++++++++----
15+
2 files changed, 71 insertions(+), 15 deletions(-)
16+
17+
diff --git a/tensorflow/core/kernels/searchsorted_op.cc b/tensorflow/core/kernels/searchsorted_op.cc
18+
index 94d18708a6a..8fc3d0da91c 100644
19+
--- a/tensorflow/core/kernels/searchsorted_op.cc
20+
+++ b/tensorflow/core/kernels/searchsorted_op.cc
21+
@@ -101,10 +101,20 @@ class UpperBoundOp : public OpKernel {
22+
const Tensor& sorted_inputs_t = ctx->input(0);
23+
const Tensor& values_t = ctx->input(1);
24+
25+
- // inputs must be at least a matrix
26+
+ // Inputs must be a matrix
27+
+ // This replicates the shape requirements for the op in array_ops.cc
28+
OP_REQUIRES(
29+
- ctx, sorted_inputs_t.shape().dims() >= 2,
30+
- errors::InvalidArgument("sorted input argument must be a matrix"));
31+
+ ctx, sorted_inputs_t.shape().dims() == 2,
32+
+ errors::InvalidArgument(absl::StrCat(
33+
+ "Shape must be rank 2 but is rank ", sorted_inputs_t.shape().dims(),
34+
+ " for "
35+
+ "`sorted_inputs` argument")));
36+
+ // Values must be a matrix
37+
+ // This replicates the shape requirements for the op in array_ops.cc
38+
+ OP_REQUIRES(ctx, values_t.shape().dims() == 2,
39+
+ errors::InvalidArgument(absl::StrCat(
40+
+ "Shape must be rank 2 but is rank ",
41+
+ values_t.shape().dims(), " for `values` argument")));
42+
// must have same batch dim_size for both
43+
OP_REQUIRES(ctx, sorted_inputs_t.dim_size(0) == values_t.dim_size(0),
44+
Status(error::INVALID_ARGUMENT,
45+
@@ -154,10 +164,20 @@ class LowerBoundOp : public OpKernel {
46+
const Tensor& sorted_inputs_t = ctx->input(0);
47+
const Tensor& values_t = ctx->input(1);
48+
49+
- // inputs must be at least a matrix
50+
+ // Inputs must be a matrix
51+
+ // This replicates the shape requirements for the op in array_ops.cc
52+
OP_REQUIRES(
53+
- ctx, sorted_inputs_t.shape().dims() >= 2,
54+
- errors::InvalidArgument("sorted input argument must be a matrix"));
55+
+ ctx, sorted_inputs_t.shape().dims() == 2,
56+
+ errors::InvalidArgument(absl::StrCat(
57+
+ "Shape must be rank 2 but is rank ", sorted_inputs_t.shape().dims(),
58+
+ " for "
59+
+ "`sorted_inputs` argument")));
60+
+ // Values must be a matrix
61+
+ // This replicates the shape requirements for the op in array_ops.cc
62+
+ OP_REQUIRES(ctx, values_t.shape().dims() == 2,
63+
+ errors::InvalidArgument(absl::StrCat(
64+
+ "Shape must be rank 2 but is rank ",
65+
+ values_t.shape().dims(), " for `values` argument")));
66+
// must have same batch dim_size for both
67+
OP_REQUIRES(ctx, sorted_inputs_t.dim_size(0) == values_t.dim_size(0),
68+
Status(error::INVALID_ARGUMENT,
69+
diff --git a/tensorflow/python/ops/array_ops_test.py b/tensorflow/python/ops/array_ops_test.py
70+
index 0c82f5ac098..4cf619d4739 100644
71+
--- a/tensorflow/python/ops/array_ops_test.py
72+
+++ b/tensorflow/python/ops/array_ops_test.py
73+
@@ -20,6 +20,7 @@ from tensorflow.python.framework import dtypes
74+
from tensorflow.python.framework import tensor_spec
75+
from tensorflow.python.framework import test_util
76+
from tensorflow.python.ops import array_ops
77+
+from tensorflow.python.ops import gen_array_ops
78+
from tensorflow.python.ops import math_ops
79+
from tensorflow.python.ops import random_ops
80+
from tensorflow.python.platform import test
81+
@@ -31,9 +32,8 @@ class ArrayOpTest(test.TestCase):
82+
# Create a tensor with an unknown dim 1.
83+
x = random_ops.random_normal([4, 10, 10])
84+
x = array_ops.gather(
85+
- x,
86+
- array_ops.reshape(array_ops.where_v2(x[0, :, 0] > 0.5), [-1]),
87+
- axis=1)
88+
+ x, array_ops.reshape(array_ops.where_v2(x[0, :, 0] > 0.5), [-1]), axis=1
89+
+ )
90+
x.shape.assert_is_compatible_with([4, None, 10])
91+
92+
with backprop.GradientTape() as tape:
93+
@@ -54,9 +54,8 @@ class ArrayOpTest(test.TestCase):
94+
# Create a tensor with an unknown dim 1.
95+
x = random_ops.random_normal([4, 10, 10])
96+
x = array_ops.gather(
97+
- x,
98+
- array_ops.reshape(array_ops.where_v2(x[0, :, 0] > 0.5), [-1]),
99+
- axis=1)
100+
+ x, array_ops.reshape(array_ops.where_v2(x[0, :, 0] > 0.5), [-1]), axis=1
101+
+ )
102+
x.shape.assert_is_compatible_with([4, None, 10])
103+
a = array_ops.reshape(x, array_ops.shape(x))
104+
a.shape.assert_is_compatible_with([4, None, 10])
105+
@@ -68,14 +67,15 @@ class ArrayOpTest(test.TestCase):
106+
c = array_ops.reshape(
107+
x,
108+
math_ops.cast(
109+
- math_ops.cast(array_ops.shape(x), dtypes.float32), dtypes.int32))
110+
+ math_ops.cast(array_ops.shape(x), dtypes.float32), dtypes.int32
111+
+ ),
112+
+ )
113+
c.shape.assert_is_compatible_with([None, None, None])
114+
115+
def testEmptyMeshgrid(self):
116+
self.assertEqual(array_ops.meshgrid(), [])
117+
118+
def testSlicedPartialShapeInference(self):
119+
-
120+
@def_function.function(autograph=False)
121+
def g(x):
122+
return array_ops.zeros([array_ops.shape(x)[0]])
123+
@@ -84,7 +84,6 @@ class ArrayOpTest(test.TestCase):
124+
self.assertAllEqual(conc.output_shapes.as_list(), [10])
125+
126+
def testIdentityOnSlicedPartialShapeInference(self):
127+
-
128+
@def_function.function(autograph=False)
129+
def g(x):
130+
return array_ops.zeros([array_ops.identity(array_ops.shape(x)[0])])
131+
@@ -106,6 +105,43 @@ class ArrayOpTest(test.TestCase):
132+
):
133+
func()
134+
135+
+ @test_util.run_in_graph_and_eager_modes
136+
+ def testUpperBoundValuesWrongRank(self):
137+
+ # Used to cause a segfault, b/266336058
138+
+ arg0 = array_ops.zeros([2, 3], dtype=dtypes.float32)
139+
+ arg1 = array_ops.zeros([2, 1, 0], dtype=dtypes.float32)
140+
+ with self.assertRaisesRegex(
141+
+ Exception, "Shape must be rank 2 but is rank 3"
142+
+ ):
143+
+ gen_array_ops.upper_bound(arg0, arg1)
144+
+
145+
+ def testLowerBoundValuesWrongRank(self):
146+
+ # Used to cause a segfault, b/266336058
147+
+ arg0 = array_ops.zeros([2, 3], dtype=dtypes.float32)
148+
+ arg1 = array_ops.zeros([2, 1, 0], dtype=dtypes.float32)
149+
+ with self.assertRaisesRegex(
150+
+ Exception, "Shape must be rank 2 but is rank 3"
151+
+ ):
152+
+ gen_array_ops.lower_bound(arg0, arg1)
153+
+
154+
+ def testUpperBoundInputsWrongRank(self):
155+
+ # Used to cause a segfault, b/266336058
156+
+ arg0 = array_ops.zeros([2, 1, 0], dtype=dtypes.float32)
157+
+ arg1 = array_ops.zeros([2, 3], dtype=dtypes.float32)
158+
+ with self.assertRaisesRegex(
159+
+ Exception, "Shape must be rank 2 but is rank 3"
160+
+ ):
161+
+ gen_array_ops.upper_bound(arg0, arg1)
162+
+
163+
+ def testLowerBoundInputsWrongRank(self):
164+
+ # Used to cause a segfault, b/266336058
165+
+ arg0 = array_ops.zeros([2, 1, 0], dtype=dtypes.float32)
166+
+ arg1 = array_ops.zeros([2, 3], dtype=dtypes.float32)
167+
+ with self.assertRaisesRegex(
168+
+ Exception, "Shape must be rank 2 but is rank 3"
169+
+ ):
170+
+ gen_array_ops.lower_bound(arg0, arg1)
171+
+
172+
173+
if __name__ == "__main__":
174+
test.main()
175+
--
176+
2.34.1
177+

SPECS/tensorflow/tensorflow.spec

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
Summary: TensorFlow is an open source machine learning framework for everyone.
22
Name: tensorflow
33
Version: 2.11.1
4-
Release: 1%{?dist}
4+
Release: 2%{?dist}
55
License: ASL 2.0
66
Vendor: Microsoft Corporation
77
Distribution: Mariner
88
Group: Development/Languages/Python
99
URL: https://www.tensorflow.org/
1010
Source0: https://github.com/tensorflow/tensorflow/archive/refs/tags/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
1111
Source1: %{name}-%{version}-cache.tar.gz
12+
Patch0: CVE-2023-33976.patch
1213
BuildRequires: bazel
1314
BuildRequires: binutils
1415
BuildRequires: build-essential
@@ -147,6 +148,9 @@ bazel --batch build --verbose_explanations //tensorflow/tools/pip_package:build
147148

148149

149150
%changelog
151+
* Thu Aug 15 2024 Aadhar Agarwal <aadagarwal@microsoft> - 2.11.1-2
152+
- Add a patch for CVE-2023-33976
153+
150154
* Wed Oct 11 2023 Mitch Zhu <mitchzhu@microsoft> - 2.11.1-1
151155
- Update to 2.11.1 to fix CVEs
152156

0 commit comments

Comments
 (0)