#1080·oatpp

[Bug] Segmentation Fault (NULL Pointer Dereference) in oatpp::String copy constructor via std::shared_ptr

Author: oneafterCreated Jan 13, 2026Updated Sep 10, 2026

Description

We discovered a Segmentation Fault vulnerability in oatpp. The crash occurs within the copy constructor of oatpp::data::type::ObjectWrapper (specifically for oatpp::String) when handling specific input.

The ASAN report indicates a READ memory access violation at address 0x000000000018. This offset suggests a NULL Pointer Dereference occurring inside the std::shared_ptr mechanism when attempting to increment the reference count of a corrupted or uninitialized object.

Environment

  • OS: Linux x86_64
  • Complier: Clang
  • Build Configuration: Release mode with ASan enabled.

Vulnerability Details

  • Target: oatpp
  • Vulnerability Type: Segmentation Fault (NULL Pointer Dereference)
  • Function: oatpp::data::type::ObjectWrapper::ObjectWrapper (Copy Constructor)
  • Location: src/oatpp/data/type/Type.hpp:172
  • Root Cause Analysis: The stack trace shows the crash happens when copying an oatpp::String:
#-3 oatpp::data::type::ObjectWrapper<...>::ObjectWrapper(...) at Type.hpp:172
#-2 std::shared_ptr<...>::shared_ptr(...)
#-0 std::__shared_count<...>::__shared_count(...)

The crash address 0x000000000018 is typical for a std::shared_ptr implementation trying to access the reference count (lock policy) inside a Control Block, where the pointer to the Control Block is NULL.

This suggests that the source oatpp::String object being copied in main (harness.cpp:53) is in an invalid state (e.g., created via a null pointer cast, or corrupted during JSON parsing) before the copy operation is attempted.

Reproduce

  1. Build oatpp and harness with Release optimization and ASAN enabled.
  2. Run the harness with the POC input.

Proof of Concept:

{"title":"Test","tags":["a","b"],"children":[null{"name":"child1","id":1}]}

ASAN report

AddressSanitizer:DEADLYSIGNAL
=================================================================
==29248==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000018 (pc 0x55b94b293978 bp 0x7ffffef0e5c0 sp 0x7ffffef0e4e0 T0)
==29248==The signal is caused by a READ memory access.
==29248==Hint: address points to the zero page.
    #0 0x55b94b293978 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/shared_ptr_base.h:1075:19
    #1 0x55b94b293978 in std::__shared_ptr<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, (__gnu_cxx::_Lock_policy)2> const&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/shared_ptr_base.h:1522:7
    #2 0x55b94b293978 in std::shared_ptr<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>::shared_ptr(std::shared_ptr<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>> const&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/shared_ptr.h:204:7
    #3 0x55b94b293978 in oatpp::data::type::ObjectWrapper<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, oatpp::data::type::__class::String>::ObjectWrapper(oatpp::data::type::ObjectWrapper<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, oatpp::data::type::__class::String> const&) /src/oatpp/src/oatpp/data/type/./Type.hpp:172:7
    #4 0x55b94b293978 in oatpp::data::type::String::String(oatpp::data::type::String const&) /src/oatpp/src/oatpp/data/type/././Primitive.hpp:118:7
    #5 0x55b94b293978 in main /src/oatpp/harness.cpp:53:39
    #6 0x7f465bb101c9  (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
    #7 0x7f465bb1028a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
    #8 0x55b94b1afbb4 in _start (/src/oatpp/build/harness+0x3bbb4) (BuildId: c98b773370d95a2400d27290cda7eb3f95d8dc64)

==29248==Register values:
rax = 0x0000000000000003  rbx = 0x00007ffffef0e4e0  rcx = 0x00000a080000008e  rdx = 0x0000000000000040  
rdi = 0x0000000000000018  rsi = 0x00000000000000f5  rbp = 0x00007ffffef0e5c0  rsp = 0x00007ffffef0e4e0  
 r8 = 0x0000000000000fb2   r9 = 0x0000000000000001  r10 = 0x0000000000000001  r11 = 0x00007f4659d00080  
r12 = 0x0000000000000001  r13 = 0x000055b94b44cea0  r14 = 0x00007f4659d00080  r15 = 0x00007f4659d00040  
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /src/oatpp/src/oatpp/data/type/./Type.hpp:172:7 in oatpp::data::type::ObjectWrapper<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, oatpp::data::type::__class::String>::ObjectWrapper(oatpp::data::type::ObjectWrapper<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, oatpp::data::type::__class::String> const&)
==29248==ABORTING