已开启
Fix CVE-2021-37686 #133
Fix CVE-2021-37686 #133
已开启
XingSongSun创建于 6月2日
2 个文件变更+680-2
@@ -0,0 +1,674 @@
1+From dfa22b348b70bb89d6d6ec0ff53973bacb4f4695 Mon Sep 17 00:00:00 2001
2+From: Mihai Maruseac <mihaimaruseac@google.com>
3+Date: Fri, 16 Jul 2021 11:09:58 -0700
4+Subject: [PATCH] Prevent a division by 0 in average ops.
5+ 
6+PiperOrigin-RevId: 385184660
7+Change-Id: I7affd4554f9b336fca29ac68f633232c094d0bd3
8+---
9+ .../internal/averagepool_quantized_test.cc | 14 +-
10+ .../internal/optimized/integer_ops/pooling.h | 4 +-
11+ .../internal/optimized/legacy_optimized_ops.h | 46 ++---
12+ .../internal/optimized/optimized_ops.h | 11 +-
13+ .../internal/reference/integer_ops/pooling.h | 8 +-
14+ .../internal/reference/legacy_reference_ops.h | 46 ++---
15+ .../lite/kernels/internal/reference/pooling.h | 8 +-
16+ tensorflow/lite/kernels/pooling.cc | 160 +++++++++---------
17+ 8 files changed, 165 insertions(+), 132 deletions(-)
18+ 
19+diff --git a/tensorflow/lite/kernels/internal/averagepool_quantized_test.cc b/tensorflow/lite/kernels/internal/averagepool_quantized_test.cc
20+index cbc863645b74b9..fea343ae6b8824 100644
21+--- a/tensorflow/lite/kernels/internal/averagepool_quantized_test.cc
22++++ b/tensorflow/lite/kernels/internal/averagepool_quantized_test.cc
23+@@ -40,12 +40,14 @@ void RunOneAveragePoolTest(const PoolParams& params,
24+ std::vector<int8> optimized_averagePool_output(buffer_size);
25+ std::vector<int8> reference_averagePool_output(buffer_size);
26+
27+- reference_integer_ops::AveragePool(params, input_shape, input_data,
28+- output_shape,
29+- reference_averagePool_output.data());
30+- optimized_integer_ops::AveragePool(params, input_shape, input_data,
31+- output_shape,
32+- optimized_averagePool_output.data());
33++ bool reference_success = reference_integer_ops::AveragePool(
34++ params, input_shape, input_data, output_shape,
35++ reference_averagePool_output.data());
36++ bool optimized_success = optimized_integer_ops::AveragePool(
37++ params, input_shape, input_data, output_shape,
38++ optimized_averagePool_output.data());
39++ EXPECT_TRUE(reference_success);
40++ EXPECT_TRUE(optimized_success);
41+
42+ for (int i = 0; i < buffer_size; i++) {
43+ EXPECT_TRUE(reference_averagePool_output[i] ==
44+diff --git a/tensorflow/lite/kernels/internal/optimized/integer_ops/pooling.h b/tensorflow/lite/kernels/internal/optimized/integer_ops/pooling.h
45+index 17495135038c65..0a6d63d3fabea6 100644
46+--- a/tensorflow/lite/kernels/internal/optimized/integer_ops/pooling.h
47++++ b/tensorflow/lite/kernels/internal/optimized/integer_ops/pooling.h
48+@@ -144,7 +144,7 @@ inline void MaxPool(const PoolParams& params, const RuntimeShape& input_shape,
49+ }
50+ }
51+
52+-inline void AveragePool(const PoolParams& params,
53++inline bool AveragePool(const PoolParams& params,
54+ const RuntimeShape& input_shape, const int8* input_data,
55+ const RuntimeShape& output_shape, int8* output_data) {
56+ ruy::profiler::ScopeLabel label("AveragePool/8bitWith32bitAccumulator");
57+@@ -192,6 +192,7 @@ inline void AveragePool(const PoolParams& params,
58+ std::min(params.filter_height, input_height - in_y_origin);
59+ const int filter_count =
60+ (filter_x_end - filter_x_start) * (filter_y_end - filter_y_start);
61++ if (filter_count == 0) return false;
62+ memset(acc, 0, tranche_depth * sizeof(acc[0]));
63+ const int8* input_ptr =
64+ input_data + depth_base +
65+@@ -267,6 +268,7 @@ inline void AveragePool(const PoolParams& params,
66+ }
67+ }
68+ }
69++ return true;
70+ }
71+
72+ } // namespace optimized_integer_ops
73+diff --git a/tensorflow/lite/kernels/internal/optimized/legacy_optimized_ops.h b/tensorflow/lite/kernels/internal/optimized/legacy_optimized_ops.h
74+index 44a553c527ab23..76b8d4c55a5e9b 100644
75+--- a/tensorflow/lite/kernels/internal/optimized/legacy_optimized_ops.h
76++++ b/tensorflow/lite/kernels/internal/optimized/legacy_optimized_ops.h
77+@@ -3761,7 +3761,7 @@ inline void BroadcastMul(const uint8* input1_data, const Dims<4>& input1_dims,
78+ output_data, output_dims);
79+ }
80+
81+-inline void AveragePool(const float* input_data, const Dims<4>& input_dims,
82++inline bool AveragePool(const float* input_data, const Dims<4>& input_dims,
83+ int stride_width, int stride_height, int pad_width,
84+ int pad_height, int kwidth, int kheight,
85+ float output_activation_min,
86+@@ -3776,35 +3776,37 @@ inline void AveragePool(const float* input_data, const Dims<4>& input_dims,
87+ params.padding_values.width = pad_width;
88+ params.float_activation_min = output_activation_min;
89+ params.float_activation_max = output_activation_max;
90+- AveragePool(params, DimsToShape(input_dims), input_data,
91+- DimsToShape(output_dims), output_data);
92++ return AveragePool(params, DimsToShape(input_dims), input_data,
93++ DimsToShape(output_dims), output_data);
94+ }
95+
96+ // legacy, for compatibility with old checked-in code
97+ template <FusedActivationFunctionType Ac>
98+-void AveragePool(const float* input_data, const Dims<4>& input_dims,
99++bool AveragePool(const float* input_data, const Dims<4>& input_dims,
100+ int stride_width, int stride_height, int pad_width,
101+ int pad_height, int kwidth, int kheight, float* output_data,
102+ const Dims<4>& output_dims) {
103+ float output_activation_min, output_activation_max;
104+ GetActivationMinMax(Ac, &output_activation_min, &output_activation_max);
105+
106+- AveragePool(input_data, input_dims, stride_width, stride_height, pad_width,
107+- pad_height, kwidth, kheight, output_activation_min,
108+- output_activation_max, output_data, output_dims);
109++ return AveragePool(input_data, input_dims, stride_width, stride_height,
110++ pad_width, pad_height, kwidth, kheight,
111++ output_activation_min, output_activation_max, output_data,
112++ output_dims);
113+ }
114+
115+ // legacy, for compatibility with old checked-in code
116+ template <FusedActivationFunctionType Ac>
117+-void AveragePool(const float* input_data, const Dims<4>& input_dims, int stride,
118++bool AveragePool(const float* input_data, const Dims<4>& input_dims, int stride,
119+ int pad_width, int pad_height, int filter_width,
120+ int filter_height, float* output_data,
121+ const Dims<4>& output_dims) {
122+- AveragePool<Ac>(input_data, input_dims, stride, stride, pad_width, pad_height,
123+- filter_width, filter_height, output_data, output_dims);
124++ return AveragePool<Ac>(input_data, input_dims, stride, stride, pad_width,
125++ pad_height, filter_width, filter_height, output_data,
126++ output_dims);
127+ }
128+
129+-inline void AveragePool(const uint8* input_data, const Dims<4>& input_dims,
130++inline bool AveragePool(const uint8* input_data, const Dims<4>& input_dims,
131+ int stride_width, int stride_height, int pad_width,
132+ int pad_height, int filter_width, int filter_height,
133+ int32 output_activation_min,
134+@@ -3819,13 +3821,13 @@ inline void AveragePool(const uint8* input_data, const Dims<4>& input_dims,
135+ params.padding_values.width = pad_width;
136+ params.quantized_activation_min = output_activation_min;
137+ params.quantized_activation_max = output_activation_max;
138+- AveragePool(params, DimsToShape(input_dims), input_data,
139+- DimsToShape(output_dims), output_data);
140++ return AveragePool(params, DimsToShape(input_dims), input_data,
141++ DimsToShape(output_dims), output_data);
142+ }
143+
144+ // legacy, for compatibility with old checked-in code
145+ template <FusedActivationFunctionType Ac>
146+-void AveragePool(const uint8* input_data, const Dims<4>& input_dims,
147++bool AveragePool(const uint8* input_data, const Dims<4>& input_dims,
148+ int stride_width, int stride_height, int pad_width,
149+ int pad_height, int filter_width, int filter_height,
150+ int32 output_activation_min, int32 output_activation_max,
151+@@ -3839,21 +3841,23 @@ void AveragePool(const uint8* input_data, const Dims<4>& input_dims,
152+ TFLITE_DCHECK_EQ(output_activation_min, 0);
153+ TFLITE_DCHECK_EQ(output_activation_max, 255);
154+ }
155+- AveragePool(input_data, input_dims, stride_width, stride_height, pad_width,
156+- pad_height, filter_width, filter_height, output_activation_min,
157+- output_activation_max, output_data, output_dims);
158++ return AveragePool(input_data, input_dims, stride_width, stride_height,
159++ pad_width, pad_height, filter_width, filter_height,
160++ output_activation_min, output_activation_max, output_data,
161++ output_dims);
162+ }
163+
164+ // legacy, for compatibility with old checked-in code
165+ template <FusedActivationFunctionType Ac>
166+-void AveragePool(const uint8* input_data, const Dims<4>& input_dims, int stride,
167++bool AveragePool(const uint8* input_data, const Dims<4>& input_dims, int stride,
168+ int pad_width, int pad_height, int filter_width,
169+ int filter_height, int32 output_activation_min,
170+ int32 output_activation_max, uint8* output_data,
171+ const Dims<4>& output_dims) {
172+- AveragePool<Ac>(input_data, input_dims, stride, stride, pad_width, pad_height,
173+- filter_width, filter_height, output_activation_min,
174+- output_activation_max, output_data, output_dims);
175++ return AveragePool<Ac>(input_data, input_dims, stride, stride, pad_width,
176++ pad_height, filter_width, filter_height,
177++ output_activation_min, output_activation_max,
178++ output_data, output_dims);
179+ }
180+
181+ inline void MaxPool(const float* input_data, const Dims<4>& input_dims,
182+diff --git a/tensorflow/lite/kernels/internal/optimized/optimized_ops.h b/tensorflow/lite/kernels/internal/optimized/optimized_ops.h
183+index a5abb056c46e6e..241405a6bbae19 100644
184+--- a/tensorflow/lite/kernels/internal/optimized/optimized_ops.h
185++++ b/tensorflow/lite/kernels/internal/optimized/optimized_ops.h
186+@@ -3172,7 +3172,7 @@ inline int NodeOffset(int b, int h, int w, int height, int width) {
187+ return (b * height + h) * width + w;
188+ }
189+
190+-inline void AveragePool(const PoolParams& params,
191++inline bool AveragePool(const PoolParams& params,
192+ const RuntimeShape& input_shape,
193+ const float* input_data,
194+ const RuntimeShape& output_shape, float* output_data) {
195+@@ -3187,6 +3187,9 @@ inline void AveragePool(const PoolParams& params,
196+ const int stride_height = params.stride_height;
197+ const int stride_width = params.stride_width;
198+
199++ if (stride_height == 0) return false;
200++ if (stride_width == 0) return false;
201++
202+ // TODO(benoitjacob) make this a proper reference impl without Eigen!
203+ const auto in_mat = MapAsMatrixWithLastDimAsRows(input_data, input_shape);
204+ auto out_mat = MapAsMatrixWithLastDimAsRows(output_data, output_shape);
205+@@ -3232,9 +3235,11 @@ inline void AveragePool(const PoolParams& params,
206+ params.float_activation_min,
207+ params.float_activation_max);
208+ }
209++
210++ return true;
211+ }
212+
213+-inline void AveragePool(const PoolParams& params,
214++inline bool AveragePool(const PoolParams& params,
215+ const RuntimeShape& input_shape,
216+ const uint8* input_data,
217+ const RuntimeShape& output_shape, uint8* output_data) {
218+@@ -3283,6 +3288,7 @@ inline void AveragePool(const PoolParams& params,
219+ std::min(params.filter_height, input_height - in_y_origin);
220+ const int filter_count =
221+ (filter_x_end - filter_x_start) * (filter_y_end - filter_y_start);
222++ if (filter_count == 0) return false;
223+ memset(acc, 0, tranche_depth * sizeof(acc[0]));
224+ const uint8* input_ptr =
225+ input_data + depth_base +
226+@@ -3369,6 +3375,7 @@ inline void AveragePool(const PoolParams& params,
227+ }
228+ }
229+ }
230++ return true;
231+ }
232+
233+ inline void MaxPool(const PoolParams& params, const RuntimeShape& input_shape,
234+diff --git a/tensorflow/lite/kernels/internal/reference/integer_ops/pooling.h b/tensorflow/lite/kernels/internal/reference/integer_ops/pooling.h
235+index 17944bc47dd5d3..2cb4dada8a66eb 100644
236+--- a/tensorflow/lite/kernels/internal/reference/integer_ops/pooling.h
237++++ b/tensorflow/lite/kernels/internal/reference/integer_ops/pooling.h
238+@@ -21,7 +21,7 @@ limitations under the License.
239+ namespace tflite {
240+ namespace reference_integer_ops {
241+
242+-inline void AveragePool(const PoolParams& params,
243++inline bool AveragePool(const PoolParams& params,
244+ const RuntimeShape& input_shape,
245+ const int8_t* input_data,
246+ const RuntimeShape& output_shape, int8_t* output_data) {
247+@@ -66,6 +66,7 @@ inline void AveragePool(const PoolParams& params,
248+ filter_count++;
249+ }
250+ }
251++ if (filter_count == 0) return false;
252+ // Round to the closest integer value.
253+ acc = acc > 0 ? (acc + filter_count / 2) / filter_count
254+ : (acc - filter_count / 2) / filter_count;
255+@@ -77,6 +78,7 @@ inline void AveragePool(const PoolParams& params,
256+ }
257+ }
258+ }
259++ return true;
260+ }
261+
262+ inline void MaxPool(const PoolParams& params, const RuntimeShape& input_shape,
263+@@ -136,7 +138,7 @@ inline void MaxPool(const PoolParams& params, const RuntimeShape& input_shape,
264+ }
265+ }
266+
267+-inline void AveragePool(const PoolParams& params,
268++inline bool AveragePool(const PoolParams& params,
269+ const RuntimeShape& input_shape,
270+ const int16_t* input_data,
271+ const RuntimeShape& output_shape,
272+@@ -182,6 +184,7 @@ inline void AveragePool(const PoolParams& params,
273+ filter_count++;
274+ }
275+ }
276++ if (filter_count == 0) return false;
277+ // Round to the closest integer value.
278+ acc = acc > 0 ? (acc + filter_count / 2) / filter_count
279+ : (acc - filter_count / 2) / filter_count;
280+@@ -193,6 +196,7 @@ inline void AveragePool(const PoolParams& params,
281+ }
282+ }
283+ }
284++ return true;
285+ }
286+
287+ inline void MaxPool(const PoolParams& params, const RuntimeShape& input_shape,
288+diff --git a/tensorflow/lite/kernels/internal/reference/legacy_reference_ops.h b/tensorflow/lite/kernels/internal/reference/legacy_reference_ops.h
289+index 2d7056fcd855e4..0b65b1f49cf380 100644
290+--- a/tensorflow/lite/kernels/internal/reference/legacy_reference_ops.h
291++++ b/tensorflow/lite/kernels/internal/reference/legacy_reference_ops.h
292+@@ -1487,7 +1487,7 @@ void Sub(const T* input1_data, const Dims<4>& input1_dims, const T* input2_data,
293+ output_data);
294+ }
295+
296+-inline void AveragePool(const float* input_data, const Dims<4>& input_dims,
297++inline bool AveragePool(const float* input_data, const Dims<4>& input_dims,
298+ int stride_width, int stride_height, int pad_width,
299+ int pad_height, int kwidth, int kheight,
300+ float output_activation_min,
301+@@ -1502,8 +1502,8 @@ inline void AveragePool(const float* input_data, const Dims<4>& input_dims,
302+ params.padding_values.width = pad_width;
303+ params.float_activation_min = output_activation_min;
304+ params.float_activation_max = output_activation_max;
305+- AveragePool(params, DimsToShape(input_dims), input_data,
306+- DimsToShape(output_dims), output_data);
307++ return AveragePool(params, DimsToShape(input_dims), input_data,
308++ DimsToShape(output_dims), output_data);
309+ }
310+
311+ // Transitional version that will be moved shortly to legacy_reference_ops, as
312+@@ -1562,29 +1562,31 @@ inline void BroadcastMul(const uint8* input1_data, const Dims<4>& input1_dims,
313+
314+ // legacy, for compatibility with old checked-in code
315+ template <FusedActivationFunctionType Ac>
316+-void AveragePool(const float* input_data, const Dims<4>& input_dims,
317++bool AveragePool(const float* input_data, const Dims<4>& input_dims,
318+ int stride_width, int stride_height, int pad_width,
319+ int pad_height, int kwidth, int kheight, float* output_data,
320+ const Dims<4>& output_dims) {
321+ float output_activation_min, output_activation_max;
322+ GetActivationMinMax(Ac, &output_activation_min, &output_activation_max);
323+
324+- AveragePool(input_data, input_dims, stride_width, stride_height, pad_width,
325+- pad_height, kwidth, kheight, output_activation_min,
326+- output_activation_max, output_data, output_dims);
327++ return AveragePool(input_data, input_dims, stride_width, stride_height,
328++ pad_width, pad_height, kwidth, kheight,
329++ output_activation_min, output_activation_max, output_data,
330++ output_dims);
331+ }
332+
333+ // legacy, for compatibility with old checked-in code
334+ template <FusedActivationFunctionType Ac>
335+-void AveragePool(const float* input_data, const Dims<4>& input_dims, int stride,
336++bool AveragePool(const float* input_data, const Dims<4>& input_dims, int stride,
337+ int pad_width, int pad_height, int filter_width,
338+ int filter_height, float* output_data,
339+ const Dims<4>& output_dims) {
340+- AveragePool<Ac>(input_data, input_dims, stride, stride, pad_width, pad_height,
341+- filter_width, filter_height, output_data, output_dims);
342++ return AveragePool<Ac>(input_data, input_dims, stride, stride, pad_width,
343++ pad_height, filter_width, filter_height, output_data,
344++ output_dims);
345+ }
346+
347+-inline void AveragePool(const uint8* input_data, const Dims<4>& input_dims,
348++inline bool AveragePool(const uint8* input_data, const Dims<4>& input_dims,
349+ int stride_width, int stride_height, int pad_width,
350+ int pad_height, int filter_width, int filter_height,
351+ int32 output_activation_min,
352+@@ -1599,13 +1601,13 @@ inline void AveragePool(const uint8* input_data, const Dims<4>& input_dims,
353+ params.padding_values.width = pad_width;
354+ params.quantized_activation_min = output_activation_min;
355+ params.quantized_activation_max = output_activation_max;
356+- AveragePool(params, DimsToShape(input_dims), input_data,
357+- DimsToShape(output_dims), output_data);
358++ return AveragePool(params, DimsToShape(input_dims), input_data,
359++ DimsToShape(output_dims), output_data);
360+ }
361+
362+ // legacy, for compatibility with old checked-in code
363+ template <FusedActivationFunctionType Ac>
364+-void AveragePool(const uint8* input_data, const Dims<4>& input_dims,
365++bool AveragePool(const uint8* input_data, const Dims<4>& input_dims,
366+ int stride_width, int stride_height, int pad_width,
367+ int pad_height, int filter_width, int filter_height,
368+ int32 output_activation_min, int32 output_activation_max,
369+@@ -1619,21 +1621,23 @@ void AveragePool(const uint8* input_data, const Dims<4>& input_dims,
370+ TFLITE_DCHECK_EQ(output_activation_min, 0);
371+ TFLITE_DCHECK_EQ(output_activation_max, 255);
372+ }
373+- AveragePool(input_data, input_dims, stride_width, stride_height, pad_width,
374+- pad_height, filter_width, filter_height, output_activation_min,
375+- output_activation_max, output_data, output_dims);
376++ return AveragePool(input_data, input_dims, stride_width, stride_height,
377++ pad_width, pad_height, filter_width, filter_height,
378++ output_activation_min, output_activation_max, output_data,
379++ output_dims);
380+ }
381+
382+ // legacy, for compatibility with old checked-in code
383+ template <FusedActivationFunctionType Ac>
384+-void AveragePool(const uint8* input_data, const Dims<4>& input_dims, int stride,
385++bool AveragePool(const uint8* input_data, const Dims<4>& input_dims, int stride,
386+ int pad_width, int pad_height, int filter_width,
387+ int filter_height, int32 output_activation_min,
388+ int32 output_activation_max, uint8* output_data,
389+ const Dims<4>& output_dims) {
390+- AveragePool<Ac>(input_data, input_dims, stride, stride, pad_width, pad_height,
391+- filter_width, filter_height, output_activation_min,
392+- output_activation_max, output_data, output_dims);
393++ return AveragePool<Ac>(input_data, input_dims, stride, stride, pad_width,
394++ pad_height, filter_width, filter_height,
395++ output_activation_min, output_activation_max,
396++ output_data, output_dims);
397+ }
398+
399+ inline void MaxPool(const float* input_data, const Dims<4>& input_dims,
400+diff --git a/tensorflow/lite/kernels/internal/reference/pooling.h b/tensorflow/lite/kernels/internal/reference/pooling.h
401+index 0872f5210c8edb..ee30b8404464ba 100644
402+--- a/tensorflow/lite/kernels/internal/reference/pooling.h
403++++ b/tensorflow/lite/kernels/internal/reference/pooling.h
404+@@ -23,7 +23,7 @@ limitations under the License.
405+ namespace tflite {
406+ namespace reference_ops {
407+
408+-inline void AveragePool(const PoolParams& params,
409++inline bool AveragePool(const PoolParams& params,
410+ const RuntimeShape& input_shape,
411+ const float* input_data,
412+ const RuntimeShape& output_shape, float* output_data) {
413+@@ -66,6 +66,7 @@ inline void AveragePool(const PoolParams& params,
414+ filter_count++;
415+ }
416+ }
417++ if (filter_count == 0) return false;
418+ const float average = total / filter_count;
419+ output_data[Offset(output_shape, batch, out_y, out_x, channel)] =
420+ ActivationFunctionWithMinMax(average, params.float_activation_min,
421+@@ -74,9 +75,10 @@ inline void AveragePool(const PoolParams& params,
422+ }
423+ }
424+ }
425++ return true;
426+ }
427+
428+-inline void AveragePool(const PoolParams& params,
429++inline bool AveragePool(const PoolParams& params,
430+ const RuntimeShape& input_shape,
431+ const uint8_t* input_data,
432+ const RuntimeShape& output_shape,
433+@@ -122,6 +124,7 @@ inline void AveragePool(const PoolParams& params,
434+ filter_count++;
435+ }
436+ }
437++ if (filter_count == 0) return false;
438+ acc = (acc + filter_count / 2) / filter_count;
439+ acc = std::max(acc, params.quantized_activation_min);
440+ acc = std::min(acc, params.quantized_activation_max);
441+@@ -131,6 +134,7 @@ inline void AveragePool(const PoolParams& params,
442+ }
443+ }
444+ }
445++ return true;
446+ }
447+
448+ inline void L2Pool(const PoolParams& params, const RuntimeShape& input_shape,
449+diff --git a/tensorflow/lite/kernels/pooling.cc b/tensorflow/lite/kernels/pooling.cc
450+index 474bd3825f4ff2..d54bd89b221511 100644
451+--- a/tensorflow/lite/kernels/pooling.cc
452++++ b/tensorflow/lite/kernels/pooling.cc
453+@@ -117,117 +117,126 @@ TfLiteStatus GenericPrepare(TfLiteContext* context, TfLiteNode* node) {
454+ }
455+
456+ template <KernelType kernel_type>
457+-void AverageEvalFloat(TfLiteContext* context, TfLiteNode* node,
458+- TfLitePoolParams* params, OpData* data,
459+- const TfLiteTensor* input, TfLiteTensor* output) {
460++TfLiteStatus AverageEvalFloat(TfLiteContext* context, TfLiteNode* node,
461++ TfLitePoolParams* params, OpData* data,
462++ const TfLiteTensor* input, TfLiteTensor* output) {
463+ float activation_min, activation_max;
464+ CalculateActivationRange(params->activation, &activation_min,
465+ &activation_max);
466+-#define TF_LITE_AVERAGE_POOL(type) \
467+- tflite::PoolParams op_params; \
468+- op_params.stride_height = params->stride_height; \
469+- op_params.stride_width = params->stride_width; \
470+- op_params.filter_height = params->filter_height; \
471+- op_params.filter_width = params->filter_width; \
472+- op_params.padding_values.height = data->padding.height; \
473+- op_params.padding_values.width = data->padding.width; \
474+- op_params.float_activation_min = activation_min; \
475+- op_params.float_activation_max = activation_max; \
476+- type::AveragePool(op_params, GetTensorShape(input), \
477+- GetTensorData<float>(input), GetTensorShape(output), \
478+- GetTensorData<float>(output))
479++#define TF_LITE_AVERAGE_POOL(type) \
480++ tflite::PoolParams op_params; \
481++ op_params.stride_height = params->stride_height; \
482++ op_params.stride_width = params->stride_width; \
483++ op_params.filter_height = params->filter_height; \
484++ op_params.filter_width = params->filter_width; \
485++ op_params.padding_values.height = data->padding.height; \
486++ op_params.padding_values.width = data->padding.width; \
487++ op_params.float_activation_min = activation_min; \
488++ op_params.float_activation_max = activation_max; \
489++ TF_LITE_ENSURE(context, type::AveragePool(op_params, GetTensorShape(input), \
490++ GetTensorData<float>(input), \
491++ GetTensorShape(output), \
492++ GetTensorData<float>(output)))
493+ if (kernel_type == kReference) {
494+ TF_LITE_AVERAGE_POOL(reference_ops);
495+ } else {
496+ TF_LITE_AVERAGE_POOL(optimized_ops);
497+ }
498+ #undef TF_LITE_AVERAGE_POOL
499++ return kTfLiteOk;
500+ }
501+
502+ template <KernelType kernel_type>
503+-void AverageEvalQuantizedUint8(TfLiteContext* context, TfLiteNode* node,
504+- TfLitePoolParams* params, OpData* data,
505+- const TfLiteTensor* input,
506+- TfLiteTensor* output) {
507++TfLiteStatus AverageEvalQuantizedUint8(TfLiteContext* context, TfLiteNode* node,
508++ TfLitePoolParams* params, OpData* data,
509++ const TfLiteTensor* input,
510++ TfLiteTensor* output) {
511+ int32_t activation_min;
512+ int32_t activation_max;
513+ (void)CalculateActivationRangeQuantized(context, params->activation, output,
514+ &activation_min, &activation_max);
515+-#define TF_LITE_AVERAGE_POOL(type) \
516+- tflite::PoolParams op_params; \
517+- op_params.stride_height = params->stride_height; \
518+- op_params.stride_width = params->stride_width; \
519+- op_params.filter_height = params->filter_height; \
520+- op_params.filter_width = params->filter_width; \
521+- op_params.padding_values.height = data->padding.height; \
522+- op_params.padding_values.width = data->padding.width; \
523+- op_params.quantized_activation_min = activation_min; \
524+- op_params.quantized_activation_max = activation_max; \
525+- type::AveragePool(op_params, GetTensorShape(input), \
526+- GetTensorData<uint8_t>(input), GetTensorShape(output), \
527+- GetTensorData<uint8_t>(output))
528++#define TF_LITE_AVERAGE_POOL(type) \
529++ tflite::PoolParams op_params; \
530++ op_params.stride_height = params->stride_height; \
531++ op_params.stride_width = params->stride_width; \
532++ op_params.filter_height = params->filter_height; \
533++ op_params.filter_width = params->filter_width; \
534++ op_params.padding_values.height = data->padding.height; \
535++ op_params.padding_values.width = data->padding.width; \
536++ op_params.quantized_activation_min = activation_min; \
537++ op_params.quantized_activation_max = activation_max; \
538++ TF_LITE_ENSURE(context, type::AveragePool(op_params, GetTensorShape(input), \
539++ GetTensorData<uint8_t>(input), \
540++ GetTensorShape(output), \
541++ GetTensorData<uint8_t>(output)))
542+ if (kernel_type == kReference) {
543+ TF_LITE_AVERAGE_POOL(reference_ops);
544+ } else {
545+ TF_LITE_AVERAGE_POOL(optimized_ops);
546+ }
547+ #undef TF_LITE_AVERAGE_POOL
548++ return kTfLiteOk;
549+ }
550+
551+ template <KernelType kernel_type>
552+-void AverageEvalQuantizedInt8(TfLiteContext* context, TfLiteNode* node,
553+- TfLitePoolParams* params, OpData* data,
554+- const TfLiteTensor* input, TfLiteTensor* output) {
555++TfLiteStatus AverageEvalQuantizedInt8(TfLiteContext* context, TfLiteNode* node,
556++ TfLitePoolParams* params, OpData* data,
557++ const TfLiteTensor* input,
558++ TfLiteTensor* output) {
559+ int32_t activation_min;
560+ int32_t activation_max;
561+
562+ (void)CalculateActivationRangeQuantized(context, params->activation, output,
563+ &activation_min, &activation_max);
564+-#define TF_LITE_AVERAGE_POOL(type) \
565+- tflite::PoolParams op_params; \
566+- op_params.stride_height = params->stride_height; \
567+- op_params.stride_width = params->stride_width; \
568+- op_params.filter_height = params->filter_height; \
569+- op_params.filter_width = params->filter_width; \
570+- op_params.padding_values.height = data->padding.height; \
571+- op_params.padding_values.width = data->padding.width; \
572+- op_params.quantized_activation_min = activation_min; \
573+- op_params.quantized_activation_max = activation_max; \
574+- type::AveragePool(op_params, GetTensorShape(input), \
575+- GetTensorData<int8_t>(input), GetTensorShape(output), \
576+- GetTensorData<int8_t>(output))
577++#define TF_LITE_AVERAGE_POOL(type) \
578++ tflite::PoolParams op_params; \
579++ op_params.stride_height = params->stride_height; \
580++ op_params.stride_width = params->stride_width; \
581++ op_params.filter_height = params->filter_height; \
582++ op_params.filter_width = params->filter_width; \
583++ op_params.padding_values.height = data->padding.height; \
584++ op_params.padding_values.width = data->padding.width; \
585++ op_params.quantized_activation_min = activation_min; \
586++ op_params.quantized_activation_max = activation_max; \
587++ TF_LITE_ENSURE(context, type::AveragePool(op_params, GetTensorShape(input), \
588++ GetTensorData<int8_t>(input), \
589++ GetTensorShape(output), \
590++ GetTensorData<int8_t>(output)))
591+ if (kernel_type == kReference) {
592+ TF_LITE_AVERAGE_POOL(reference_integer_ops);
593+ } else {
594+ TF_LITE_AVERAGE_POOL(optimized_integer_ops);
595+ }
596+ #undef TF_LITE_AVERAGE_POOL
597++ return kTfLiteOk;
598+ }
599+
600+ template <KernelType kernel_type>
601+-void AverageEvalQuantizedInt16(TfLiteContext* context, TfLiteNode* node,
602+- TfLitePoolParams* params, OpData* data,
603+- const TfLiteTensor* input,
604+- TfLiteTensor* output) {
605++TfLiteStatus AverageEvalQuantizedInt16(TfLiteContext* context, TfLiteNode* node,
606++ TfLitePoolParams* params, OpData* data,
607++ const TfLiteTensor* input,
608++ TfLiteTensor* output) {
609+ int32_t activation_min;
610+ int32_t activation_max;
611+ CalculateActivationRangeQuantized(context, params->activation, output,
612+ &activation_min, &activation_max);
613+-#define TF_LITE_AVERAGE_POOL(type) \
614+- tflite::PoolParams op_params; \
615+- op_params.stride_height = params->stride_height; \
616+- op_params.stride_width = params->stride_width; \
617+- op_params.filter_height = params->filter_height; \
618+- op_params.filter_width = params->filter_width; \
619+- op_params.padding_values.height = data->padding.height; \
620+- op_params.padding_values.width = data->padding.width; \
621+- op_params.quantized_activation_min = activation_min; \
622+- op_params.quantized_activation_max = activation_max; \
623+- type::AveragePool(op_params, GetTensorShape(input), \
624+- GetTensorData<int16_t>(input), GetTensorShape(output), \
625+- GetTensorData<int16_t>(output))
626++#define TF_LITE_AVERAGE_POOL(type) \
627++ tflite::PoolParams op_params; \
628++ op_params.stride_height = params->stride_height; \
629++ op_params.stride_width = params->stride_width; \
630++ op_params.filter_height = params->filter_height; \
631++ op_params.filter_width = params->filter_width; \
632++ op_params.padding_values.height = data->padding.height; \
633++ op_params.padding_values.width = data->padding.width; \
634++ op_params.quantized_activation_min = activation_min; \
635++ op_params.quantized_activation_max = activation_max; \
636++ TF_LITE_ENSURE(context, type::AveragePool(op_params, GetTensorShape(input), \
637++ GetTensorData<int16_t>(input), \
638++ GetTensorShape(output), \
639++ GetTensorData<int16_t>(output)))
640+ TF_LITE_AVERAGE_POOL(reference_integer_ops);
641+ #undef TF_LITE_AVERAGE_POOL
642++ return kTfLiteOk;
643+ }
644+
645+ template <KernelType kernel_type>
646+@@ -380,20 +389,17 @@ TfLiteStatus AverageEval(TfLiteContext* context, TfLiteNode* node) {
647+ TF_LITE_ENSURE_OK(context, GetInputSafe(context, node, 0, &input));
648+ switch (input->type) { // Already know in/out types are same.
649+ case kTfLiteFloat32:
650+- AverageEvalFloat<kernel_type>(context, node, params, data, input, output);
651+- break;
652++ return AverageEvalFloat<kernel_type>(context, node, params, data, input,
653++ output);
654+ case kTfLiteUInt8:
655+- AverageEvalQuantizedUint8<kernel_type>(context, node, params, data, input,
656+- output);
657+- break;
658++ return AverageEvalQuantizedUint8<kernel_type>(context, node, params, data,
659++ input, output);
660+ case kTfLiteInt8:
661+- AverageEvalQuantizedInt8<kernel_type>(context, node, params, data, input,
662+- output);
663+- break;
664++ return AverageEvalQuantizedInt8<kernel_type>(context, node, params, data,
665++ input, output);
666+ case kTfLiteInt16:
667+- AverageEvalQuantizedInt16<kernel_type>(context, node, params, data, input,
668+- output);
669+- break;
670++ return AverageEvalQuantizedInt16<kernel_type>(context, node, params, data,
671++ input, output);
672+ default:
673+ TF_LITE_KERNEL_LOG(context, "Type %s not currently supported.",
674+ TfLiteTypeGetName(input->type));
@@ -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,7 @@ 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-37686.patch
20%endif21%endif
21Requires: python3-future python3-numpy python3-six python3-astunparse python3-google-pasta python3-opt-einsum22Requires: 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 23Requires: python3-typing-extensions python3-wrapt python3-h5py python3-protobuf python3-grpcio python3-absl-py
@@ -45,6 +46,7 @@ TensorFlow provides stable Python and C++ APIs, as well as non-guaranteed backwa
45 46 
46%prep47%prep
47%setup -n %{name}-%{version}48%setup -n %{name}-%{version}
49+%patch -P 1101 -p1
48%patch 0 -p150%patch 0 -p1
49%patch 1 -p151%patch 1 -p1
50%patch 2 -p152%patch 2 -p1
@@ -84,6 +86,8 @@ bazel --output_user_root=`pwd`/../output_user_root build --nofetch --host_copt=-
84%{_bindir}/*86%{_bindir}/*
85 87 
86%changelog88%changelog
89+* Tue Jun 02 2026 sunwenhan <sunwenhan@xfusion.com> - 2.12.1-6
90+- Fix CVE-2021-37686
87* Tue Mar 03 2026 megranate wangkunjie@xfuison.com - 2.12.1-591* Tue Mar 03 2026 megranate wangkunjie@xfuison.com - 2.12.1-5
88- fix CVE-2026-249292- fix CVE-2026-2492
89 93 
@@ -122,4 +126,4 @@ bazel --output_user_root=`pwd`/../output_user_root build --nofetch --host_copt=-
122- fix some cves126- fix some cves
123 127 
124* Wed Sep 30 2020 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.3.1-1128* Wed Sep 30 2020 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.3.1-1
125-- Package init129+- Package init