Skip to content

Wrong initialization of fixed_address_empty_string causes ShutdownProtobufLibrary to fail #8129

Closed
@danieljoos

Description

@danieljoos

What version of protobuf and what language are you using?
Version: v3.14.0, master
Language: C++

What operating system (Linux, Windows, ...) and version?
Windows

What runtime / compiler are you using (e.g., python version or gcc version)
MSVC 14.27.29110
Platform Toolset v142 (Visual Studio 2019)
Debug Runtime

What did you do?
Steps to reproduce the behavior:

#include "addressbook.pb.h"

int main() {
	::google::protobuf::ShutdownProtobufLibrary();
}

with addressbook.proto (it really doesn't matter at all):

syntax = "proto3";

package tutorial;

message AddressBook {
  string name = 1;
}

What did you expect to see

No exception when execution ShutdownProtobufLibrary(). The program should just run-through without any issues.

What did you see instead?

The program throws an exception when run in Debug mode on executing ShutdownProtobufLibrary().

It is caused by attempting to destruct a broken std::string stored ::google::protobuf::internal::fixed_address_empty_string.value.
The reason is that the implementation relies on a static initialization of that variable. The variable fixed_address_empty_string is default constructed to dummy (here

constexpr EmptyString() : dummy{} {}
).
However, as the initialization of static global variables is undefined across translation units in C++, it is possible that InitProtobufDefaultsImpl() (
::new (static_cast<void*>(&fixed_address_empty_string.value)) std::string();
) is called before the initialization of the fixed_address_empty_string (
fixed_address_empty_string; // NOLINT
). This causes the allocated std::string value to get broken, as the dummy value gets initialized "over" the existing std::string object.

This happens, for example when including a generated protobuf header file as a call to AddDescriptors() is forced there to happen during dynamic initialization time.

The actual exception is thrown by the MSCV STL on destruction as the std::string is now malformed.

Anything else we should know about your project / environment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions