Store to misaligned address in `REPLACE_NEAR` macro
jiridanek opened this issue · 1 comments
jiridanek commented
I am using amd64 architecture. I enabled AddressSanitizer and UndefinedBehavior sanitizer in GCC. My tests produce the following undefined behavior error:
cpp_stub.h:244:13: runtime error: store to misaligned address 0x0000004bc2e1 for type 'int', which requires 4 byte alignment
0x0000004bc2e1: note: pointer points here
fd ff ff e9 25 8a 3e 69 00 68 2b 00 00 00 e9 30 fd ff ff ff 25 82 3e 69 00 68 2c 00 00 00 e9 20
^
pc_0x9534d7###func_void Stub::set<int (*)(char*, unsigned long, char const*, __va_list_tag*), int (*)(char*, unsigned long, char const*, ...)>(int (*)(char*, unsigned long, char const*, __va_list_tag*), int (*)(char*, unsigned long, char const*, ...))###file_/home/jdanek/repos/qpid/qpid-dispatch/tests/cpp-stub/cpp_stub.h###line_244###obj_(c_unittests+0x9534d7)
pc_0x94cb4b###func__DOCTEST_ANON_FUNC_2###file_/home/jdanek/repos/qpid/qpid-dispatch/tests/c_unittests/test_terminus.cpp###line_88###obj_(c_unittests+0x94cb4b)
pc_0x7fc0ce###func_doctest::Context::run()###file_/home/jdanek/repos/qpid/qpid-dispatch/tests/c_unittests/doctest.h###line_6486###obj_(c_unittests+0x7fc0ce)
pc_0x7ff7c0###func_main###file_/home/jdanek/repos/qpid/qpid-dispatch/tests/c_unittests/doctest.h###line_6571###obj_(c_unittests+0x7ff7c0)
pc_0x7f11e90db55f###func___libc_start_call_main###file_<null>###line_0###obj_(libc.so.6+0x2d55f)
pc_0x7f11e90db60b###func___libc_start_main_impl###file_<null>###line_0###obj_(libc.so.6+0x2d60b)
pc_0x4bec64###func__start###file_<null>###line_0###obj_(c_unittests+0x4bec64)
The stub.cpp
code is
REPLACE_NEAR(this, fn, fn_stub);
The macro is
//5 byte(jmp rel32)
#define REPLACE_NEAR(t, fn, fn_stub)\
*fn = 0xE9;\
*(int *)(fn + 1) = (int)(fn_stub - fn - CODESIZE_MIN);\
//CACHEFLUSH((char *)fn, CODESIZE);
Looking into code, there is more statements suffering from this, e.g. *(long long *)(fn + 2) = (long long)fn_stub;\
in the same file.
For a solution, I am thinking that std::copy or memcpy should solve this, but it feels more clumsy than the current code and it may need helper variable.
coolxv commented
//5 byte(jmp rel32)
#define REPLACE_NEAR(t, fn, fn_stub)\
*fn = 0xE9;\
int an = (int)(fn_stub - fn - CODESIZE_MIN);\
*(fn + 1) = ((char*)&an)[0];\
*(fn + 2) = ((char*)&an)[1];\
*(fn + 3) = ((char*)&an)[2];\
*(fn + 4) = ((char*)&an)[3];\
//CACHEFLUSH((char *)fn, CODESIZE);