1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-21 19:33:03 +04:00

Fix null pointer dereference in G-API stateful kernels

Fixes #28095

Problem:
- Stateful kernels dereference null state pointer on line 446 in gcpukernel.hpp
- jinboson confirmed state_ptr is null on x86 Ubuntu (7 hours ago)
- Causes crash with std::shared_ptr assertion on LoongArch64 and strict platforms

Solution (addressing Copilot review feedback from PR #28096):
1. Added null pointer check using CV_Error instead of CV_Assert:
   - CV_Assert with && 'message' doesn't display the message correctly
   - CV_Error properly reports cv::Error::StsNullPtr with clear message

2. Fixed test kernels to properly initialize state using std::make_shared:
   - GOCVStInvalidResize: Initialize state in setup()
   - GOCVCountStateSetups: Initialize state before incrementing counter
   - Used std::make_shared<int>() for modern C++ best practice

Impact:
- Prevents crashes on platforms with strict null pointer checking
- Provides actionable error message for developers
- Fixes StatefulKernel.StateInitOnceInRegularMode and InvalidReallocatingKernel tests
This commit is contained in:
Ghazi-raad
2025-12-06 12:45:48 +00:00
parent 324d489e71
commit 5a0679b862
2 changed files with 12 additions and 4 deletions
@@ -443,7 +443,12 @@ struct OCVStCallHelper<Impl, std::tuple<Ins...>, std::tuple<Outs...>> :
template<int... IIs, int... OIs>
static void call_impl(GCPUContext &ctx, detail::Seq<IIs...>, detail::Seq<OIs...>)
{
auto& st = *ctx.state().get<std::shared_ptr<typename Impl::State>>();
auto state_ptr = ctx.state().get<std::shared_ptr<typename Impl::State>>();
if (state_ptr == nullptr) {
CV_Error(cv::Error::StsNullPtr, "Stateful kernel's state is not initialized. "
"Make sure the setup() function properly initializes the state.");
}
auto& st = *state_ptr;
call_and_postprocess<decltype(get_in<Ins>::get(ctx, IIs))...>
::call(st, get_in<Ins>::get(ctx, IIs)..., get_out<Outs>::get(ctx, OIs)...);
}
@@ -103,8 +103,10 @@ namespace
GAPI_OCV_KERNEL_ST(GOCVStInvalidResize, GStInvalidResize, int)
{
static void setup(const cv::GMatDesc, cv::Size, double, double, int,
std::shared_ptr<int> &/* state */)
{ }
std::shared_ptr<int> &state)
{
state = std::make_shared<int>();
}
static void run(const cv::Mat& in, cv::Size sz, double fx, double fy, int interp,
cv::Mat &out, int& /* state */)
@@ -150,9 +152,10 @@ namespace
GAPI_OCV_KERNEL_ST(GOCVCountStateSetups, GCountStateSetups, int)
{
static void setup(const cv::GMatDesc &, std::shared_ptr<int> &,
static void setup(const cv::GMatDesc &, std::shared_ptr<int> &state,
const cv::GCompileArgs &compileArgs)
{
state = std::make_shared<int>();
auto params = cv::gapi::getCompileArg<CountStateSetupsParams>(compileArgs)
.value_or(CountStateSetupsParams { });
if (params.pSetupsCount != nullptr) {