How to validate length of received byte array, which is not null terminated?
I have a C\C++ code that receives a structure over the network, from this form:
struct DataStruct
{
int DataLen;
BYTE* Data;
开发者_Python百科}
The code I have runs over Data
in a loop of DataLen
times and processes the data.
...The problem:
After the code came to security experts for penetration tests, they prepared a fake application which sends this struct with DataLen
bigger than the real length of Data
. This causes, of course, an access violation exception.
So, the question is - how can I validate the real length of the received Data
? Is it possible without changing the structure?
Thanks in advance.
Nice security experts! I wish my company had a department like that.
Whenever data is received from the network, the network IO reports the number of bytes actually written to the buffer, whether you used read(2)
, recv(2)
, or boost::asio::async_read
or anything else I've seen. Typical use case when there's a "number of bytes to follow" field in the header of your data structure, is to repeatedly call read/recv/etc until that many bytes were received (or until error occurred), and only then it should construct and return your DataStruct (or report error).
You know how much bytes you have received, so just compare it with DataLen
.
It is impossible without changing the structure. Data received from TCP/IP socket is plain stream. Logically, it is not divided into packets. Physical packet may contain one or more DataStruct instances, one DataStruct instance can be divided to two or more physical packets. Current information structure can be used only if there are no communication errors or invalid packets.
Corruption is easy if you haven't any intrinsic limitation.
Some protection mechanisms would be:
- Try to
realloc()
the buffer, within some acceptable size (ifData
is dynamic) - Exceptions are friends: use
SIGSEGV
insignal(2)
,signal(7)
andsetjmp(2)
to do some useful try/catch code structure. See Combining setjmp()/longjmp() and Signal Handling for a quick introduction on this topic. Usesigaction(2)
to go deeper (by getting the faulty address;).
精彩评论