GitHub does not insert automatic links and smart code snippets in these files, so we have to do it manually. PiperOrigin-RevId: 333195707 Change-Id: I1e2fed8ff207fbfce6eb8fb2b910d12bcab4100c
85 lines
3.6 KiB
Markdown
85 lines
3.6 KiB
Markdown
## TFSA-2020-005: Out of bounds access in TFLite operators
|
|
|
|
### CVE Number
|
|
CVE-2020-15211
|
|
|
|
### Impact
|
|
In TensorFlow Lite, saved models in the flatbuffer format use a double indexing
|
|
scheme: a model has a set of subgraphs, each subgraph has a set of operators and
|
|
each operator has a set of input/output tensors. The flatbuffer format uses
|
|
indices for the tensors, indexing into an array of tensors that is owned by the
|
|
subgraph. This results in a pattern of double array indexing when trying to
|
|
[get the data of each
|
|
tensor](https://github.com/tensorflow/tensorflow/blob/0e68f4d3295eb0281a517c3662f6698992b7b2cf/tensorflow/lite/kernels/kernel_util.cc#L36):
|
|
```cc
|
|
return &context->tensors[node->inputs->data[index]];
|
|
```
|
|
|
|
However, some operators can have some tensors be optional. To handle this
|
|
scenario, the flatbuffer model uses a negative `-1` value as [index for these tensors](https://github.com/tensorflow/tensorflow/blob/0e68f4d3295eb0281a517c3662f6698992b7b2cf/tensorflow/lite/c/common.h#L82):
|
|
```cc
|
|
#define kTfLiteOptionalTensor (-1)
|
|
```
|
|
|
|
This results in [special casing during validation at model loading
|
|
time](https://github.com/tensorflow/tensorflow/blob/0e68f4d3295eb0281a517c3662f6698992b7b2cf/tensorflow/lite/core/subgraph.cc#L566-L580):
|
|
```cc
|
|
for (int i = 0; i < length; i++) {
|
|
int index = indices[i];
|
|
// Continue if index == kTfLiteOptionalTensor before additional comparisons
|
|
// below, size_t(-1) is always >= context_tensors_size.
|
|
if (index == kTfLiteOptionalTensor) {
|
|
continue;
|
|
}
|
|
if (index < 0 || static_cast<size_t>(index) >= context_.tensors_size) {
|
|
ReportError(
|
|
"Invalid tensor index %d in %s. The subgraph has %d tensors\n", index,
|
|
label, context_.tensors_size);
|
|
consistent_ = false;
|
|
return kTfLiteError;
|
|
}
|
|
}
|
|
```
|
|
|
|
Unfortunately, this means that the `-1` index is a valid tensor index for any
|
|
operator, including those that don't expect optional inputs and including for
|
|
output tensors. Thus, this allows writing and reading from outside the bounds of
|
|
heap allocated arrays, although only at a specific offset from the start of
|
|
these arrays.
|
|
|
|
This results in both read and write gadgets, albeit very limited in scope.
|
|
|
|
### Vulnerable Versions
|
|
TensorFlow 1.15.0, 1.15.1, 1.15.2, 1.15.3, 2.0.0, 2.0.1, 2.0.2, 2.1.0, 2.1.1,
|
|
2.2.0, 2.3.0.
|
|
|
|
### Patches
|
|
We have patched the issue in several commits
|
|
([46d5b0852](https://github.com/tensorflow/tensorflow/commit/46d5b0852),
|
|
[00302787b7](https://github.com/tensorflow/tensorflow/commit/00302787b7),
|
|
[e11f5558](https://github.com/tensorflow/tensorflow/commit/e11f5558),
|
|
[cd31fd0ce](https://github.com/tensorflow/tensorflow/commit/cd31fd0ce),
|
|
[1970c21](https://github.com/tensorflow/tensorflow/commit/1970c21), and
|
|
[fff2c83](https://github.com/tensorflow/tensorflow/commit/fff2c83)). We will
|
|
release patch releases for all versions between 1.15 and 2.3.
|
|
|
|
We recommend users to upgrade to TensorFlow 1.15.4, 2.0.3, 2.1.2, 2.2.1, or
|
|
2.3.1.
|
|
|
|
### Workarounds
|
|
A potential workaround would be to add a custom `Verifier` to the model loading
|
|
code to ensure that only operators which accept optional inputs use the `-1`
|
|
special value and only for the tensors that they expect to be optional. Since
|
|
this allow-list type approach is erro-prone, we advise upgrading to the patched
|
|
code.
|
|
|
|
### For more information
|
|
Please 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.
|
|
|
|
### Attribution
|
|
This vulnerability has been reported by members of the Aivul Team from Qihoo
|
|
360.
|