已开启
Fix CVE-2021-37686 #133
XingSongSun创建于 6月2日
Fix CVE-2021-37686 #133
已开启
共 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 | + 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 0 | 1 | %global _empty_manifest_terminate_build 0 |
| 2 | Name: tensorflow | 2 | Name: tensorflow |
| 3 | Version: 2.12.1 | 3 | Version: 2.12.1 |
| 4 | -Release: 5 | 4 | +Release: 6 |
| 5 | Summary: An Open Source Machine Learning Framework for Everyone | 5 | Summary: An Open Source Machine Learning Framework for Everyone |
| 6 | License: Apache License 2.0 | 6 | License: Apache License 2.0 |
| 7 | URL: https://www.tensorflow.org/ | 7 | URL: https://www.tensorflow.org/ |
| @@ -17,6 +17,7 @@ Patch1000: aarch64_external_files.patch | |||
| 17 | %endif | 17 | %endif |
| 18 | %ifarch riscv64 | 18 | %ifarch riscv64 |
| 19 | Patch1100: riscv64_external_files.patch | 19 | Patch1100: riscv64_external_files.patch |
| 20 | +Patch1101: backport-CVE-2021-37686.patch | ||
| 20 | %endif | 21 | %endif |
| 21 | Requires: python3-future python3-numpy python3-six python3-astunparse python3-google-pasta python3-opt-einsum | 22 | Requires: python3-future python3-numpy python3-six python3-astunparse python3-google-pasta python3-opt-einsum |
| 22 | Requires: python3-typing-extensions python3-wrapt python3-h5py python3-protobuf python3-grpcio python3-absl-py | 23 | Requires: 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 | %prep | 47 | %prep |
| 47 | %setup -n %{name}-%{version} | 48 | %setup -n %{name}-%{version} |
| 49 | +%patch -P 1101 -p1 | ||
| 48 | %patch 0 -p1 | 50 | %patch 0 -p1 |
| 49 | %patch 1 -p1 | 51 | %patch 1 -p1 |
| 50 | %patch 2 -p1 | 52 | %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 | %changelog | 88 | %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-5 | 91 | * Tue Mar 03 2026 megranate wangkunjie@xfuison.com - 2.12.1-5 |
| 88 | - fix CVE-2026-2492 | 92 | - 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 cves | 126 | - fix some cves |
| 123 | 127 | ||
| 124 | * Wed Sep 30 2020 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.3.1-1 | 128 | * Wed Sep 30 2020 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.3.1-1 |
| 125 | -- Package init | 129 | +- Package init |