Assertion failure based denial of service in Tensorflow
Description
TensorFlow *Bincount operations can be forced into CHECK-fail denial-of-service via specially crafted inputs.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
TensorFlow *Bincount operations can be forced into CHECK-fail denial-of-service via specially crafted inputs.
Vulnerability
The implementation of *Bincount operations in TensorFlow (including Bincount, SparseBincount and DenseBincount) in versions prior to 2.5.3, 2.6.3, 2.7.1, and 2.8.0 is vulnerable to a denial-of-service caused by a CHECK-fail. Certain conditions on the input arguments, such as invalid size or weights tensor dimensions, are not properly validated during shape inference or kernel implementation ([1]). This allows attackers to trigger assertion failures during output tensor allocation, crashing the process. The affected code resides in tensorflow/core/kernels/bincount_op.cc ([4]).
Exploitation
An attacker requires the ability to invoke one of the *Bincount operations (e.g., via a Python script or a TensorFlow serving endpoint) with meticulously crafted input tensors ([1]). The attacker does not need elevated privileges; any user who can supply model inputs or call the affected ops can exploit the flaw. By providing values that bypass the incomplete input validation, the attacker forces a CHECK failure during tensor allocation, leading to immediate process termination.
Impact
Successful exploitation results in a denial of service (DoS). The TensorFlow process crashes with a CHECK failure, making the service unavailable until restarted. There is no data confidentiality or integrity impact; the sole outcome is availability loss ([1]).
Mitigation
The fix was included in TensorFlow 2.8.0, released on 2022-02-03 ([1]). Patches were also cherry-picked to TensorFlow 2.7.1, 2.6.3, and 2.5.3 ([1]). Users running affected versions should upgrade to one of the patched releases immediately. No workarounds are available; blocking untrusted users from invoking the *Bincount operations is the only alternative until upgrading.
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
tensorflowPyPI | < 2.5.3 | 2.5.3 |
tensorflowPyPI | >= 2.6.0, < 2.6.3 | 2.6.3 |
tensorflowPyPI | >= 2.7.0, < 2.7.1 | 2.7.1 |
tensorflow-cpuPyPI | < 2.5.3 | 2.5.3 |
tensorflow-cpuPyPI | >= 2.6.0, < 2.6.3 | 2.6.3 |
tensorflow-cpuPyPI | >= 2.7.0, < 2.7.1 | 2.7.1 |
tensorflow-gpuPyPI | < 2.5.3 | 2.5.3 |
tensorflow-gpuPyPI | >= 2.6.0, < 2.6.3 | 2.6.3 |
tensorflow-gpuPyPI | >= 2.7.0, < 2.7.1 | 2.7.1 |
Affected products
5- osv-coords4 versions
< 2.5.3+ 3 more
- (no CPE)range: < 2.5.3
- (no CPE)range: < 2.5.3
- (no CPE)range: < 2.5.3
- (no CPE)range: < 2.5.3
Patches
17019ce4f6892Fix check-fail when bincount ops are passed invalid values.
3 files changed · +56 −0
tensorflow/core/kernels/bincount_op.cc+9 −0 modified@@ -276,6 +276,9 @@ class DenseBincountOp : public OpKernel { const Tensor& size_t = ctx->input(1); const Tensor& weights = ctx->input(2); + OP_REQUIRES(ctx, size_t.dims() == 0, + errors::InvalidArgument("Shape must be rank 0 but is rank ", + size_t.dims())); Tidx size = size_t.scalar<Tidx>()(); OP_REQUIRES( ctx, size >= 0, @@ -372,6 +375,9 @@ class SparseBincountOp : public OpKernel { const auto weights = ctx->input(4).flat<T>(); const int64_t weights_size = weights.size(); + OP_REQUIRES(ctx, size_t.dims() == 0, + errors::InvalidArgument("Shape must be rank 0 but is rank ", + size_t.dims())); Tidx size = size_t.scalar<Tidx>()(); OP_REQUIRES( ctx, size >= 0, @@ -462,6 +468,9 @@ class RaggedBincountOp : public OpKernel { const auto weights = ctx->input(3).flat<T>(); const int64_t weights_size = weights.size(); + OP_REQUIRES(ctx, size_t.dims() == 0, + errors::InvalidArgument("Shape must be rank 0 but is rank ", + size_t.dims())); Tidx size = size_t.scalar<Tidx>()(); OP_REQUIRES( ctx, size >= 0,
tensorflow/core/ops/math_ops.cc+13 −0 modified@@ -1699,6 +1699,11 @@ REGISTER_OP("Bincount") return Status::OK(); } + if (size_tensor->dims() != 0) { + return errors::InvalidArgument("Shape must be rank 0 but is rank ", + size_tensor->dims()); + } + // Return `[size]` shape if size is known. int32_t size_val = size_tensor->scalar<int32>()(); if (size_val < 0) { @@ -1730,6 +1735,10 @@ REGISTER_OP("DenseBincount") c->set_output(0, c->UnknownShape()); return Status::OK(); } + if (size_tensor->dims() != 0) { + return errors::InvalidArgument("Shape must be rank 0 but is rank ", + size_tensor->dims()); + } int64_t size_val; DataType dtype; @@ -1771,6 +1780,10 @@ REGISTER_OP("SparseBincount") c->set_output(0, c->UnknownShape()); return Status::OK(); } + if (size_tensor->dims() != 0) { + return errors::InvalidArgument("Shape must be rank 0 but is rank ", + size_tensor->dims()); + } int64_t size_val; DataType dtype;
tensorflow/python/kernel_tests/math_ops/bincount_op_test.py+34 −0 modified@@ -344,6 +344,14 @@ def test_invalid_rank(self): gen_math_ops.dense_bincount( input=[[[1, 2, 3], [0, 3, 2]]], weights=[], size=10)) + @test_util.run_in_graph_and_eager_modes + def test_size_is_not_scalar(self): # b/206619828 + with self.assertRaisesRegex((ValueError, errors.InvalidArgumentError), + "Shape must be rank 0 but is rank 1"): + self.evaluate( + gen_math_ops.dense_bincount( + input=[0], size=[1, 1], weights=[3], binary_output=False)) + class SparseBincountOpTest(test_util.TensorFlowTestCase, parameterized.TestCase): @@ -511,6 +519,19 @@ def test_sparse_bincount_col_reduce_binary(self, dtype): weights=[], binary_output=True))) + @test_util.run_in_graph_and_eager_modes + def test_size_is_not_scalar(self): # b/206619828 + with self.assertRaisesRegex((ValueError, errors.InvalidArgumentError), + "Shape must be rank 0 but is rank 1"): + self.evaluate( + gen_math_ops.sparse_bincount( + indices=[[0], [1]], + values=[0, 0], + dense_shape=[1, 1], + size=[1, 1], + weights=[0, 0], + binary_output=False)) + class RaggedBincountOpTest(test_util.TensorFlowTestCase, parameterized.TestCase): @@ -650,6 +671,19 @@ def test_ragged_bincount_binary_np_with_weights(self, dtype): size=size, binary_output=True))) + @test_util.run_in_graph_and_eager_modes + def test_size_is_not_scalar(self): # b/206619828 + with self.assertRaisesRegex((ValueError, errors.InvalidArgumentError), + "Shape must be rank 0 but is rank 1"): + self.evaluate( + gen_math_ops.ragged_bincount( + splits=[0, 0, 1], + values=[1], + size=[1, 1], + weights=[0, 0, 0], + binary_output=False, + name=None)) + if __name__ == "__main__": googletest.main()
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-f2vv-v9cg-qhh7ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-21737ghsaADVISORY
- github.com/pypa/advisory-database/tree/main/vulns/tensorflow-cpu/PYSEC-2022-61.yamlghsaWEB
- github.com/pypa/advisory-database/tree/main/vulns/tensorflow-gpu/PYSEC-2022-116.yamlghsaWEB
- github.com/tensorflow/tensorflow/blob/5100e359aef5c8021f2e71c7b986420b85ce7b3d/tensorflow/core/kernels/bincount_op.ccghsax_refsource_MISCWEB
- github.com/tensorflow/tensorflow/commit/7019ce4f68925fd01cdafde26f8d8c938f47e6f9ghsax_refsource_MISCWEB
- github.com/tensorflow/tensorflow/security/advisories/GHSA-f2vv-v9cg-qhh7ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.