Skip to content

Wrong initialization of fixed_address_empty_string causes ShutdownProtobufLibrary to fail #8129

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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions