Opened 5 years ago

Last modified 5 years ago

#13092 new Bugs

Serializing pointer makes sanitizer complain about "reference binding to misaligned address"

Reported by: fiesh@… Owned by: Robert Ramey
Milestone: To Be Determined Component: serialization
Version: Boost 1.63.0 Severity: Problem
Keywords: Cc:

Description

Consider the following program:

#include <memory>
#include <sstream>

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/shared_ptr.hpp>

struct S
{
	int i;
	char c;

	template <class Archive>
	void serialize(Archive & ar, const unsigned int version)
	{
		ar & i;
		ar & c;
	}
};

int main()
{
	const auto s0 = std::make_shared<S>();
	s0->i = 42;
	s0->c = 'c';

	std::stringstream ss;

	{
		boost::archive::text_oarchive oa(ss);
		oa << s0;
	}

	std::shared_ptr<S> s1;
	{
		boost::archive::text_iarchive ia(ss);
		ia >> s1;
	}

	return 0;
}

What is important is that we use a pointer to the struct.

I then get the following output, which seems to be a real issue probably mitigated by x86's lax requirements on alignment:

% g++ -lboost_serialization -fsanitize=address -fsanitize=leak -fsanitize=undefined -fsanitize=shift -fsanitize=integer-divide-by-zero -fsanitize=unreachable -fsanitize=vla-bound -fsanitize=null -fsanitize=return -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=object-size -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=nonnull-attribute -fsanitize=returns-nonnull-attribute -fsanitize=bool -fsanitize=enum -fno-sanitize=vptr t.cpp&& LD_PRELOAD=/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libasan.so ./a.out
% LD_PRELOAD=/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libasan.so ./a.out
/usr/include/boost/archive/detail/iserializer.hpp:540:19: runtime error: reference binding to misaligned address 0x000000000002 for type 'struct S', which requires 4 byte alignment
0x000000000002: note: pointer points here
<memory cannot be printed>
/usr/include/boost/archive/detail/iserializer.hpp:541:67: runtime error: reference binding to misaligned address 0x000000000002 for type 'const struct S', which requires 4 byte alignment
0x000000000002: note: pointer points here
<memory cannot be printed>
% LD_PRELOAD=/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libasan.so ./a.out
% LD_PRELOAD=/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libasan.so ./a.out
/usr/include/boost/archive/detail/iserializer.hpp:540:19: runtime error: reference binding to misaligned address 0x000000000002 for type 'struct S', which requires 4 byte alignment
0x000000000002: note: pointer points here
<memory cannot be printed>
/usr/include/boost/archive/detail/iserializer.hpp:541:67: runtime error: reference binding to misaligned address 0x000000000002 for type 'const struct S', which requires 4 byte alignment
0x000000000002: note: pointer points here
<memory cannot be printed>

Note how it only occurs sometimes, probably depending on what memory address happened to have been returned.

Change History (1)

comment:1 by Robert Ramey, 5 years ago

I can't reproduce this on my system. The best would be if you could send a fix. Note the comment at line 540 of serialization suggests that this problem was foreseen at some point. It's probably caused by something higher in the call stack and a likely fix would be to use some alignment.

Note: See TracTickets for help on using tickets.