Buffer overflow when the received NetIO message is less than 32 bits long
src/libNetioHW/NetioHandler.cpp
209: memcpy(buffer, (uint32_t *)&data[offset], numWords*4);
I run into an issue at the line 209 when two consecutive messages are received: 48 bits followed by 8 bits (the AMAC responses to the read and write commands). For the second message, the std::vector<uint8_t> data
vector contains only 1 byte at the offset
, and numWords
= 1. Therefore, memcpy
grabs bytes past the end of data
. At line 222 the result of memcpy
in buffer
(8 bit message + a chunk of the previous message) is converted into a 32 bit RawData that is returned to the user.
I am going to try memcpy
only the number of bytes in the message (msg_size - my_headersize
), instead of 32 bit words. If that goes well, I will make a merge request.
A gdb session that shows the issue:
(gdb) b NetioHandler.cpp:209
(gdb) b NetioHandler.cpp:222
**48 bit message:**
209 memcpy(buffer, (uint32_t *)&data[offset], numWords*4);
(gdb) p msg_size
$1 = 14
(gdb) p my_headersize
$2 = 8
(gdb) p/x data
$3 = std::vector of length 14, capacity 14 = {0xe, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0xab, 0xa, 0xb4, 0x2c, 0x17, 0x27}
(gdb) x/8x buffer
0x7fffd8005370: 0x00000000 0x00000000 0x00000000 0x00000000
0x7fffd8005380: 0x00000000 0x00000000 0x0001bc81 0x00000000
(gdb) n
212 nlog->debug("msg size: {}", numWords);
(gdb) x/8x buffer
0x7fffd8005370: 0x2cb40aab 0x00002717 0x00000000 0x00000000
0x7fffd8005380: 0x00000000 0x00000000 0x0001bc81 0x00000000
(gdb) c
Continuing.
222 std::unique_ptr<RawData> rdp = std::unique_ptr<RawData>(rd);
(gdb) p rd->words
$4 = 2
(gdb) p/x rd->buf[0]
$5 = 0x2cb40aab
(gdb) p/x rd->buf[1]
$6 = 0x2717
(gdb) c
Continuing.
**8 bit message:**
209 memcpy(buffer, (uint32_t *)&data[offset], numWords*4);
(gdb) p msg_size
$7 = 9
(gdb) p my_headersize
$8 = 8
(gdb) p/x data
$9 = std::vector of length 9, capacity 9 = {0x9, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0xac}
(gdb) x/8x buffer
0x7fffd8005350: 0x00000000 0x00000000 0x2cb40aab 0x00002717
0x7fffd8005360: 0x00000000 0x00000000 0x00000025 0x00000000
(gdb) n
212 nlog->debug("msg size: {}", numWords);
(gdb) x/8x buffer
0x7fffd8005350: 0x2cb40aac 0x00000000 0x2cb40aab 0x00002717
0x7fffd8005360: 0x00000000 0x00000000 0x00000025 0x00000000
(gdb) c
Continuing.
222 std::unique_ptr<RawData> rdp = std::unique_ptr<RawData>(rd);
(gdb) p rd->words
$10 = 1
(gdb) p/x rd->buf[0]
$11 = 0x2cb40aac
-- instead of $11 = 0x2cb40aac
I expect $11 = 0xac
, only the last byte of data
and zeros.