I'm introducing myself to socket programming in C/C++, and am using send()
and recv()
to exchange data between a client and server program over TCP
sockets.
Here are some relevant excerpts from my code:
server.c:
char recv_data[1024];
// Socket setup and so on ommited...
bytes_recieved = recv(connected, recv_data, 1024, 0);
recv_data[bytes_recieved] = '\0';
client.c:
char send_data[1024];
// Setup ommited...
send(connected, send_data, strlen(send_data), 0);
Does recv()
itself provide any protection against buffer overflows? For instance if I changed the 3rd argument to recv()
to something higher than the buffer pointed to by recv_data
(e.g. 4000) - would this cause a buffer overflow? (I've actually tried doing this, but can't seem to trigger a segfault).
I'm actually trying to create an intentionally vulnerable server program to better understand these issues, which is why I've tried to overflow via recv()
.
Amendment:
Not unrelated, would be finding out why client.c
above would ever send more than the 1024
bytes specified by strlen(send_data)
. I'm using gets(send_data)
to populate that buffer from standard input, but if I enter many more than 1024 bytes via standard in, the server.c
program shows that it receives ALL THE BYTES! :). Does the strlen(send_data)
for send()
not restrict the number of bytes sent?
For instance if I changed the 3rd argument to recv() to something higher than the buffer pointed to by recv_data (e.g. 4000) - would this cause a buffer overflow?
Ofcourse yes. If the network buffer has data of 4000 bytes, it will put it in the buffer. The key point is that, recv like any other C API which takes a buffer and it's length believes that the caller will pass the actual length of the buffer and if the caller passes incorrect length, then the fault lies with the caller and it can lead to undefined behavior.
In C when you pass arrays to a function, there is no way for the called function to know the size of the array. So, all API(s) just rely on the input provided by you.
char recv_data[1024];
// Socket setup and so on ommited...
bytes_recieved = recv(connected, recv_data, 1024, 0);
recv_data[bytes_recieved] = '\0';
The above code can cause trouble in more ways than one. It will lead to undefined behavior under the following conditions:
(a) If recv returns -1
, then you are directly indexing into the recv_data buffer without checking the return value
(b) If recv returns 1024
, then again, it leads to out of bound access as the array of size 1024
should be accessed from 0
to 1023
.