protocolbuffers / protobuf

Protocol Buffers - Google's data interchange format
http://protobuf.dev
Other
65.81k stars 15.51k forks source link

[C++] core dump when ParsePartialFromArray is called #19315

Closed fbucafusco closed 2 days ago

fbucafusco commented 3 days ago

What version of protobuf and what language are you using?

Version: release 28.3 Language: C++

What operating system (Linux, Windows, ...) and version? Operating System: Linux Mint 22
Kernel: Linux 6.8.0-48-generic Architecture: x86-64

What runtime / compiler are you using (e.g., python version or gcc version) gcc (Ubuntu 13.2.0-23ubuntu4) 13.2.0

What did you do? I have a big message structure but I will only copy the, I think, relevant part of it where the sanitizer is complaining.

message DeviceConfigMsg
{ 
    GeneralConfig     general_config  = 2;
    NetConfig             net_config          = 3; 
    repeated CEConfig ce_configs      = 5;
}

message CEConfig
{
    uint32            ce_id        = 1; 
    bytes             identifier   = 3;
    string            display_name = 6; 
    repeated EPConfig ep_configs   = 4; 
}

then I compiled the .proto into .pb.cc/hh

My c++ code looks like this:

#include "device_configuration_message.pb.h"

void test()
{
    const uint8_t  msg_in[] =  {  a valid serialized message   };,
    size_t msg_in_len = sizeof(msg_in);

    std::unique_ptr<DeviceConfigMsg> msg = std::make_unique<DeviceConfigMsg>();

    if ( msg )
    {
        if (!msg->ParseFromArray( msg_in , static_cast<int>(msg_in_len))   ) 
        {
        //error
        } 
    }

    //use msg content
}

What did you expect to see at least the parsing goes ok and the function exits.

What did you see instead? originally, a core dump, and then this sanitizer report

==2439447==ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x5e669d5b1200 in thread T0

0 0x7a896eaff5e8 in operator delete(void*, unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:164

#1 0x5e669d36ecfa in Data::~Data() /home/franco/les_cpp/api_messages/src_generated/data.pb.cc:1502
#2 0x5e669d368ae3 in EPConfig::SharedDtor() /home/franco/les_cpp/api_messages/src_generated/endpoint_config.pb.cc:253
#3 0x5e669d366fa7 in EPConfig::~EPConfig() /home/franco/les_cpp/api_messages/src_generated/endpoint_config.pb.cc:246
#4 0x7a896e6ef42c in bool google::protobuf::internal::MergeFromImpl<false>(google::protobuf::stringpiece_internal::StringPiece, google::protobuf::MessageLite*, google::protobuf::MessageLite::ParseFlags) (/lib/x86_64-linux-gnu/libprotobuf.so.32+0xef42c) (BuildId: cb18bf20ee806ab086b168dc9a95c8bd5bcb6ed6)
#5 0x5e669d3050f1 in test_device_config_0() /home/franco/les_cpp/examples/protobuf_test.h:54

Make sure you include information that can help us debug (full error message, exception listing, stack trace, logs). I think, yes.

Anything else we should know about your project / environment

fbucafusco commented 3 days ago

Update, I chopped some fields from the main message. (repeated EPConfig ep_configs = 4; ) I am doing that because I know the serialized array does not have anything there. I ran the test again, and was still failing (note that the asan output tells something about EPConfig) Then, I removed the

message EPConfig
{
....
} 

fro the proto file...

and the asan error dissapeared

I still have another error, I will post it in a new issue.

fbucafusco commented 3 days ago

BTW all my proto files are linked, and the definitions are included from one to the other,. I just tried to simplify the explanation. So, when I removed the import "endpoint_config.proto"; in my main proto, the only diff in the pb.h was #include "endpoint_config.pb.h"

fbucafusco commented 3 days ago

Ok, I also tried to use ParsePartialFromArray (because my msg had missing fields) and asan kicks in anyways with the same error,

fbucafusco commented 2 days ago

I have found the issue. I was using a different protoc version. I thought I had all built from the source, but still cmake was running the systemwise version of it.