Opened 15 months ago
#21850 new defect
NAT (slirp.c) may corrupt incoming data when followed by close.
Reported by: | henryk paluch | Owned by: | |
---|---|---|---|
Component: | network/NAT | Version: | VirtualBox-7.0.10 |
Keywords: | nat slirp truncated shifted skewed | Cc: | kabat, paluch |
Guest type: | other | Host type: | Windows |
Description
When using guest with "NAT" interface and connecting to remote TCP server, it may happen that when server closes connection right after sending data, the data in guest will be corrupted. First byte will be removed and length will be one byte less.
Example:
- correct data read from server (returned most of time):
ABCD
- but sometimes guest get just
BCD
Tip: all test files and proposed patch are also available on public GitHub page: https://github.com/hpaluch-pil/vbox-nat-bug-test provided under MIT license (to no CLA needed).
How to reproduce:
- setup Remote server with Linux or any other OS that is capable to run PERL
- run provided perl script
tcp_service.pl
on that remote host. - Setup Linux (or any other OS with PERL 5) as VirtualBox Guest (tested 7.0.10) and ensure that "NAT" interface is used to access remote server.
- Run provided perl script
tcp_client.pl
with arguments like:
./tcp_client.pl IP_OF_REMOTE_HOST 99999
- It will run for some time receiving correct data (no error reported).
For example:
Iteration #179... Connected from 10.0.2.15:55642 to 192.168.10.54:9999. <- data from server: 'ABCDEFGH' 8 bytes Data OK. Closing connection...
- But sooner or later it will fail with error:
Iteration #180... Connected from 10.0.2.15:55648 to 192.168.10.54:9999. <- data from server: 'BCDEFGH' 7 bytes Unexpected data 'BCDEFGH' <> 'ABCDEFGH' at ./tcp_client.pl line 59.
As can be clearly seen, 1st byte of data is missing entirely and total received data length is 1 byte shorter.
After lot of debug logging I have found that there is a bug in slirp.c
where it may try to close socket too eagerly even when received data
was not yet processed by tcp_input
. It can be easily identified by
evaluating so->so_state
which will be 0 (which means - unknown/uninitialized).
Therefore I created patch that defers close of such sockets until they were at least once processed by tcp_input
. It is provided in patch file close-fix-slirp.c.patch
. However it needs more testing.
Attachments (3)
Change History (3)
by , 15 months ago
Attachment: | tcp_service.pl added |
---|
by , 15 months ago
Attachment: | tcp_client.pl added |
---|
Example Tcp Client to be run as VirtualBox Guest and have to use "NAT" Interface to access remote Server
Example Tcp Server to be run on remote Linux Host