Skip to content

Commit dc47f83

Browse files
rascanifacebook-github-bot
authored andcommitted
Validate non-null data pointer in Tensor accessors
Summary: Add null-data-pointer validation to all six data accessor methods on the `Tensor` class (`const_data_ptr`, `mutable_data_ptr`, and deprecated `data_ptr` — two overloads each). The check fires when `numel() > 0` but the underlying `data_` pointer is null, which indicates an invalid tensor state. This prevents null pointer dereferences in all 225+ kernel implementations that call these accessors. The Lionhead fuzzer (`FuzzKernels` harness, T234178948) has been filing 50-100+ crash tasks because it constructs tensors with non-zero numel but null data pointers. Every kernel that dereferences the result of `const_data_ptr()` crashes. This centralized check catches the invalid state at the accessor level, eliminating the entire class of fuzzer findings. Tensors with `numel() == 0` and a null data pointer remain valid (empty tensors). Differential Revision: D103467785
1 parent a3dd0fa commit dc47f83

1 file changed

Lines changed: 25 additions & 0 deletions

File tree

runtime/core/portable_type/tensor.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#pragma once
1010

11+
#include <executorch/runtime/platform/assert.h>
1112
#include <executorch/runtime/platform/compiler.h>
1213

1314
#include <executorch/runtime/core/portable_type/tensor_impl.h>
@@ -118,33 +119,57 @@ class Tensor {
118119
/// Returns a pointer of type T to the constant underlying data blob.
119120
template <typename T>
120121
inline const T* const_data_ptr() const {
122+
ET_CHECK_MSG(
123+
numel() == 0 || impl_->data() != nullptr,
124+
"Tensor has non-zero numel (%zd) but null data pointer",
125+
(ssize_t)numel());
121126
return impl_->data<T>();
122127
}
123128

124129
/// Returns a pointer to the constant underlying data blob.
125130
inline const void* const_data_ptr() const {
131+
ET_CHECK_MSG(
132+
numel() == 0 || impl_->data() != nullptr,
133+
"Tensor has non-zero numel (%zd) but null data pointer",
134+
(ssize_t)numel());
126135
return impl_->data();
127136
}
128137

129138
/// Returns a pointer of type T to the mutable underlying data blob.
130139
template <typename T>
131140
inline T* mutable_data_ptr() const {
141+
ET_CHECK_MSG(
142+
numel() == 0 || impl_->data() != nullptr,
143+
"Tensor has non-zero numel (%zd) but null data pointer",
144+
(ssize_t)numel());
132145
return impl_->mutable_data<T>();
133146
}
134147

135148
/// Returns a pointer to the mutable underlying data blob.
136149
inline void* mutable_data_ptr() const {
150+
ET_CHECK_MSG(
151+
numel() == 0 || impl_->data() != nullptr,
152+
"Tensor has non-zero numel (%zd) but null data pointer",
153+
(ssize_t)numel());
137154
return impl_->mutable_data();
138155
}
139156

140157
/// DEPRECATED: Use const_data_ptr or mutable_data_ptr instead.
141158
template <typename T>
142159
ET_DEPRECATED inline T* data_ptr() const {
160+
ET_CHECK_MSG(
161+
numel() == 0 || impl_->data() != nullptr,
162+
"Tensor has non-zero numel (%zd) but null data pointer",
163+
(ssize_t)numel());
143164
return impl_->mutable_data<T>();
144165
}
145166

146167
/// DEPRECATED: Use const_data_ptr or mutable_data_ptr instead.
147168
ET_DEPRECATED inline void* data_ptr() const {
169+
ET_CHECK_MSG(
170+
numel() == 0 || impl_->data() != nullptr,
171+
"Tensor has non-zero numel (%zd) but null data pointer",
172+
(ssize_t)numel());
148173
return impl_->mutable_data();
149174
}
150175

0 commit comments

Comments
 (0)