Skip to content

Commit 084cb4d

Browse files
MikeJKellyKevinARM
authored andcommitted
IVGCVSW-7404 Out of bounds detection
* Added test to ensure that all inputs and outputs do not go out of bounds. Signed-off-by: Mike Kelly <mike.kelly@arm.com> Change-Id: Ia97e85f71e46cd2203306243e4dcbc23e0f29ec1
1 parent 0637bf3 commit 084cb4d

5 files changed

Lines changed: 136 additions & 12 deletions

File tree

ArmnnPreparedModel.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
2+
// Copyright © 2017-2023 Arm Ltd and Contributors. All rights reserved.
33
// SPDX-License-Identifier: MIT
44
//
55

@@ -218,18 +218,27 @@ Return<V1_0::ErrorStatus> ArmnnPreparedModel<HalVersion>::execute(
218218
NotifyCallbackAndCheck(callback, V1_0::ErrorStatus::GENERAL_FAILURE, "ArmnnPreparedModel::execute");
219219
return V1_0::ErrorStatus::GENERAL_FAILURE;
220220
}
221+
221222
// add the inputs and outputs with their data
222223
try
223224
{
224225
pInputTensors->reserve(request.inputs.size());
225226
for (unsigned int i = 0; i < request.inputs.size(); i++)
226227
{
227228
const auto& inputArg = request.inputs[i];
228-
229229
armnn::TensorInfo inputTensorInfo = m_Runtime->GetInputTensorInfo(m_NetworkId, i);
230230
// pInputTensors (of type InputTensors) is composed of a vector of ConstTensors.
231231
// Therefore, set all TensorInfo isConstant parameters of input Tensors to true.
232232
inputTensorInfo.SetConstant();
233+
auto result = ValidateRequestArgument<V1_0::ErrorStatus, V1_0::Request>(request,
234+
inputTensorInfo,
235+
inputArg,
236+
"input");
237+
if (result != V1_0::ErrorStatus::NONE)
238+
{
239+
return result;
240+
}
241+
233242
const armnn::Tensor inputTensor = GetTensorForRequestArgument(inputArg, inputTensorInfo, *pMemPools);
234243
if (inputTensor.GetMemoryArea() == nullptr)
235244
{
@@ -244,8 +253,17 @@ Return<V1_0::ErrorStatus> ArmnnPreparedModel<HalVersion>::execute(
244253
for (unsigned int i = 0; i < request.outputs.size(); i++)
245254
{
246255
const auto& outputArg = request.outputs[i];
247-
248256
const armnn::TensorInfo outputTensorInfo = m_Runtime->GetOutputTensorInfo(m_NetworkId, i);
257+
auto result = ValidateRequestArgument<V1_0::ErrorStatus, V1_0::Request>(request,
258+
outputTensorInfo,
259+
outputArg,
260+
"output");
261+
262+
if (result != V1_0::ErrorStatus::NONE)
263+
{
264+
return result;
265+
}
266+
249267
const armnn::Tensor outputTensor = GetTensorForRequestArgument(outputArg, outputTensorInfo, *pMemPools);
250268
if (outputTensor.GetMemoryArea() == nullptr)
251269
{

ArmnnPreparedModel_1_2.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
2+
// Copyright © 2017-2023 Arm Ltd and Contributors. All rights reserved.
33
// SPDX-License-Identifier: MIT
44
//
55

@@ -312,11 +312,20 @@ Return<V1_0::ErrorStatus> ArmnnPreparedModel_1_2<HalVersion>::PrepareMemoryForIn
312312
for (unsigned int i = 0; i < request.inputs.size(); i++)
313313
{
314314
const auto& inputArg = request.inputs[i];
315-
316315
armnn::TensorInfo inputTensorInfo = m_Runtime->GetInputTensorInfo(m_NetworkId, i);
317316
// inputs (of type InputTensors) is composed of a vector of ConstTensors.
318317
// Therefore, set all TensorInfo isConstant parameters of input Tensors to true.
319318
inputTensorInfo.SetConstant();
319+
auto result = ValidateRequestArgument<V1_0::ErrorStatus, V1_0::Request>(request,
320+
inputTensorInfo,
321+
inputArg,
322+
"input");
323+
324+
if (result != V1_0::ErrorStatus::NONE)
325+
{
326+
return result;
327+
}
328+
320329
const armnn::Tensor inputTensor = GetTensorForRequestArgument(inputArg, inputTensorInfo, memPools);
321330

322331
if (inputTensor.GetMemoryArea() == nullptr)
@@ -342,8 +351,17 @@ Return<V1_0::ErrorStatus> ArmnnPreparedModel_1_2<HalVersion>::PrepareMemoryForOu
342351
for (unsigned int i = 0; i < request.outputs.size(); i++)
343352
{
344353
const auto& outputArg = request.outputs[i];
354+
armnn::TensorInfo outputTensorInfo = m_Runtime->GetOutputTensorInfo(m_NetworkId, i);
355+
auto result = ValidateRequestArgument<V1_0::ErrorStatus, V1_0::Request>(request,
356+
outputTensorInfo,
357+
outputArg,
358+
"output");
359+
360+
if (result != V1_0::ErrorStatus::NONE)
361+
{
362+
return result;
363+
}
345364

346-
const armnn::TensorInfo outputTensorInfo = m_Runtime->GetOutputTensorInfo(m_NetworkId, i);
347365
const armnn::Tensor outputTensor = GetTensorForRequestArgument(outputArg, outputTensorInfo, memPools);
348366
if (outputTensor.GetMemoryArea() == nullptr)
349367
{

ArmnnPreparedModel_1_3.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
2+
// Copyright © 2020-2023 Arm Ltd and Contributors. All rights reserved.
33
// SPDX-License-Identifier: MIT
44
//
55
// Note: the ArmnnFencedExecutionCallback and code snippet in the executeFenced() function
@@ -510,11 +510,20 @@ Return<V1_3::ErrorStatus> ArmnnPreparedModel_1_3<HalVersion>::PrepareMemoryForIn
510510
for (unsigned int i = 0; i < request.inputs.size(); i++)
511511
{
512512
const auto& inputArg = request.inputs[i];
513-
514513
armnn::TensorInfo inputTensorInfo = m_Runtime->GetInputTensorInfo(m_NetworkId, i);
515514
// inputs (of type InputTensors) is composed of a vector of ConstTensors.
516515
// Therefore, set all TensorInfo isConstant parameters of input Tensors to true.
517516
inputTensorInfo.SetConstant();
517+
auto result = ValidateRequestArgument<V1_3::ErrorStatus, V1_3::Request>(request,
518+
inputTensorInfo,
519+
inputArg,
520+
"input");
521+
522+
if (result != V1_3::ErrorStatus::NONE)
523+
{
524+
return result;
525+
}
526+
518527
const armnn::Tensor inputTensor = GetTensorForRequestArgument(inputArg, inputTensorInfo, memPools);
519528

520529
if (inputTensor.GetMemoryArea() == nullptr)
@@ -540,15 +549,24 @@ Return<V1_3::ErrorStatus> ArmnnPreparedModel_1_3<HalVersion>::PrepareMemoryForOu
540549
for (unsigned int i = 0; i < request.outputs.size(); i++)
541550
{
542551
const auto& outputArg = request.outputs[i];
543-
544552
armnn::TensorInfo outputTensorInfo = m_Runtime->GetOutputTensorInfo(m_NetworkId, i);
553+
auto result = ValidateRequestArgument<V1_3::ErrorStatus, V1_3::Request>(request,
554+
outputTensorInfo,
555+
outputArg,
556+
"output");
557+
558+
if (result != V1_3::ErrorStatus::NONE)
559+
{
560+
return result;
561+
}
562+
545563
const armnn::Tensor outputTensor = GetTensorForRequestArgument(outputArg, outputTensorInfo, memPools);
564+
546565
if (outputTensor.GetMemoryArea() == nullptr)
547566
{
548567
ALOGE("Cannot execute request. Error converting request output %u to tensor", i);
549568
return V1_3::ErrorStatus::GENERAL_FAILURE;
550569
}
551-
552570
const size_t outputSize = outputTensorInfo.GetNumBytes();
553571

554572
unsigned int count = 0;

Utils.cpp

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
2+
// Copyright © 2017-2021,2023 Arm Ltd and Contributors. All rights reserved.
33
// SPDX-License-Identifier: MIT
44
//
55

@@ -767,4 +767,67 @@ void CommitPools(std::vector<::android::nn::RunTimePoolInfo>& memPools)
767767
#endif
768768
}
769769
}
770+
771+
size_t GetSize(const V1_0::Request& request, const V1_0::RequestArgument& requestArgument)
772+
{
773+
return request.pools[requestArgument.location.poolIndex].size();
774+
}
775+
776+
#ifdef ARMNN_ANDROID_NN_V1_3
777+
size_t GetSize(const V1_3::Request& request, const V1_0::RequestArgument& requestArgument)
778+
{
779+
if (request.pools[requestArgument.location.poolIndex].getDiscriminator() ==
780+
V1_3::Request::MemoryPool::hidl_discriminator::hidlMemory)
781+
{
782+
return request.pools[requestArgument.location.poolIndex].hidlMemory().size();
783+
}
784+
else
785+
{
786+
return 0;
787+
}
788+
}
789+
#endif
790+
791+
template <typename ErrorStatus, typename Request>
792+
ErrorStatus ValidateRequestArgument(const Request& request,
793+
const armnn::TensorInfo& tensorInfo,
794+
const V1_0::RequestArgument& requestArgument,
795+
std::string descString)
796+
{
797+
if (requestArgument.location.poolIndex >= request.pools.size())
798+
{
799+
std::string err = fmt::format("Invalid {} pool at index {} the pool index is greater than the number "
800+
"of available pools {}",
801+
descString, requestArgument.location.poolIndex, request.pools.size());
802+
ALOGE(err.c_str());
803+
return ErrorStatus::GENERAL_FAILURE;
804+
}
805+
const size_t size = GetSize(request, requestArgument);
806+
size_t totalLength = tensorInfo.GetNumBytes();
807+
808+
if (static_cast<size_t>(requestArgument.location.offset) + totalLength > size)
809+
{
810+
std::string err = fmt::format("Invalid {} pool at index {} the offset {} and length {} are greater "
811+
"than the pool size {}", descString, requestArgument.location.poolIndex,
812+
requestArgument.location.offset, totalLength, size);
813+
ALOGE(err.c_str());
814+
return ErrorStatus::GENERAL_FAILURE;
815+
}
816+
return ErrorStatus::NONE;
817+
}
818+
819+
template V1_0::ErrorStatus ValidateRequestArgument<V1_0::ErrorStatus, V1_0::Request>(
820+
const V1_0::Request& request,
821+
const armnn::TensorInfo& tensorInfo,
822+
const V1_0::RequestArgument& requestArgument,
823+
std::string descString);
824+
825+
#ifdef ARMNN_ANDROID_NN_V1_3
826+
template V1_3::ErrorStatus ValidateRequestArgument<V1_3::ErrorStatus, V1_3::Request>(
827+
const V1_3::Request& request,
828+
const armnn::TensorInfo& tensorInfo,
829+
const V1_0::RequestArgument& requestArgument,
830+
std::string descString);
831+
#endif
832+
770833
} // namespace armnn_driver

Utils.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright © 2017 Arm Ltd. All rights reserved.
2+
// Copyright © 2017-2021,2023 Arm Ltd and Contributors. All rights reserved.
33
// SPDX-License-Identifier: MIT
44
//
55

@@ -11,6 +11,8 @@
1111
#include <NeuralNetworks.h>
1212
#include <Utils.h>
1313

14+
#include <fmt/format.h>
15+
1416
#include <vector>
1517
#include <string>
1618
#include <fstream>
@@ -194,4 +196,9 @@ inline V1_2::OutputShape ComputeShape(const armnn::TensorInfo& info)
194196

195197
void CommitPools(std::vector<::android::nn::RunTimePoolInfo>& memPools);
196198

199+
template <typename ErrorStatus, typename Request>
200+
ErrorStatus ValidateRequestArgument(const Request& request,
201+
const armnn::TensorInfo& tensorInfo,
202+
const V1_0::RequestArgument& requestArgument,
203+
std::string descString);
197204
} // namespace armnn_driver

0 commit comments

Comments
 (0)