epics-base / pvDataCPP

pvDataCPP is an EPICS V4 C++ module
https://epics-base.github.io/pvDataCPP/
Other
6 stars 16 forks source link

fix for use-after-free warning #82

Closed dirk-zimoch closed 1 year ago

mdavidsaver commented 1 year ago

Excerpting an email I sent to Dirk.

> /usr/local/epics/base-7.0.7/include/pv/sharedVector.h:486:13: warning: pointer
> used after ‘void operator delete [](void*)’ [-Wuse-after-free]
>    486 |             delete[] temp;
>        |             ^~~~~~~~~~~~~
...
> I get the same warning compiling ntscalarArrayTest.cpp, ntnameValueTest.cpp,
> ntscalarMultiChannelTest.cpp, nttableTest.cpp, ntmatrixTest.cpp,
> ntcontinuumTest.cpp, nthistogramTest.cpp, and pvaClientNTMultiData.cpp.
>
> Any idea what the problem is?

This warning refers to a imo. fairly unlikely error path in
shared_vector::resize() where a new array buffer has been
allocated, but a subsequent small allocation in the
shared_ptr constructor has failed.

Looking at the present logic (below), the only way I can see for
a use-after-free (really double free) would be if A) both size()
and copy() were "noexcept", and B) for reset() to contain an
equivalent catch, delete, rethrow block.

A) is true iff the element type constructor is also "noexcept",
which is the case for the simple element types, but not for
std::string and PVStructure.  So the try{} block is still needed
in these cases.

I thought that B) was false.  However, a closer reading shows
me that it is true.

https://en.cppreference.com/w/cpp/memory/shared_ptr/reset#Exceptions

> 3-4) std::bad_alloc if required additional memory could not be obtained.
>      May throw implementation-defined exception for other errors. d(ptr)
>      is called if an exception occurs.