Skip to content
Permalink
Browse files Browse the repository at this point in the history
Resolve a sanitizer issue with invalid char -> bool conversion.
When printing a tensor, we get it's data as a `const char*` array (since that's the underlying storage) and then we typecast it to the element type. However, conversions from `char` to `bool` are undefined if the `char` is not `0` or `1`, so sanitizers/fuzzers will crash.

To fix, we're creating a mutable `char` array to convert the chars to 0/1, according to bool rules.

Discovered via internal fuzzing.

PiperOrigin-RevId: 482297563
  • Loading branch information
mihaimaruseac authored and tensorflower-gardener committed Oct 19, 2022
1 parent d404994 commit 1be7437
Showing 1 changed file with 27 additions and 5 deletions.
32 changes: 27 additions & 5 deletions tensorflow/core/framework/tensor.cc
Expand Up @@ -29,6 +29,7 @@ limitations under the License.

#include "tensorflow/core/framework/tensor.h"

#include <memory>
#include <utility>

#include "absl/strings/escaping.h"
Expand Down Expand Up @@ -1183,12 +1184,10 @@ void PrintOneDimV2(int dim_index, const gtl::InlinedVector<int64, 4>& shape,
}

template <typename T>
string SummarizeArray(int64_t limit, int64_t num_elts,
const TensorShape& tensor_shape, const char* data,
const bool print_v2) {
string SummarizeArrayInternal(int64_t limit, int64_t num_elts,
const TensorShape& tensor_shape, const T* array,
const bool print_v2) {
string ret;
const T* array = reinterpret_cast<const T*>(data);

const gtl::InlinedVector<int64_t, 4> shape = tensor_shape.dim_sizes();
if (shape.empty()) {
for (int64_t i = 0; i < limit; ++i) {
Expand All @@ -1211,6 +1210,29 @@ string SummarizeArray(int64_t limit, int64_t num_elts,

return ret;
}

template <typename T>
string SummarizeArray(int64_t limit, int64_t num_elts,
const TensorShape& tensor_shape, const char* data,
const bool print_v2) {
const T* array = reinterpret_cast<const T*>(data);
return SummarizeArrayInternal<T>(limit, num_elts, tensor_shape, array,
print_v2);
}

template <>
string SummarizeArray<bool>(int64_t limit, int64_t num_elts,
const TensorShape& tensor_shape, const char* data,
const bool print_v2) {
// We first convert all chars to be 0/1 to not get InvalidEnumValue sanitizer
// error
auto mutable_data = std::unique_ptr<char[]>(new char[num_elts]);
for (int64_t i = 0; i < num_elts; ++i)
mutable_data.get()[i] = data[i] ? 1 : 0;
bool* array = reinterpret_cast<bool*>(mutable_data.get());
return SummarizeArrayInternal<bool>(limit, num_elts, tensor_shape, array,
print_v2);
}
} // namespace

string Tensor::SummarizeValue(int64_t max_entries, bool print_v2) const {
Expand Down

0 comments on commit 1be7437

Please sign in to comment.