Commit b41b3f5
issue: 4669986 Fix integer underflow on EINTR
The udp_send tests were failing sporadically due to integer
underflow when recv() was interrupted by a signal.
In the receive accumulation loops, when recv() returned -1 with
errno=EINTR (interrupted system call):
while (received < recvsize) {
rc = recv(fd, buff + received, sizeof(buff) - received, 0);
if (rc < 0 && errno != EINTR) {
break;
}
received += static_cast<size_t>(rc); // BUG
}
The EINTR check allowed the loop to continue, but then proceeded
to cast rc=-1 to size_t, creating a huge positive value
(0xFFFFFFFFFFFFFFFF on 64-bit). This caused 'received' to exceed
'recvsize', terminating the loop immediately with an empty buffer.
The sporadic nature occurred because signal delivery (timer signals,
scheduling signals, etc.) is non-deterministic. Most runs succeeded,
but occasional signal interruption triggered the bug.
The fix adds a check to only accumulate positive receive counts:
if (rc > 0) {
received += static_cast<size_t>(rc);
}
This correctly handles three cases:
- rc > 0: Data received, accumulate and continue
- rc == 0: Zero-length UDP datagram, skip and continue
- rc < 0 with EINTR: Interrupted, retry without accumulating
- rc < 0 with other errno: Error, break from loop
Fixed in two test locations:
- udp_send.null_iov_elements (line 524)
- udp_send.null_iov_elements_single_iov (line 744)
Note: tcp_send.cc already had correct handling with explicit
rc==0 check, preventing this class of bug.
Signed-off-by: Tomer Cabouly <[email protected]>1 parent 8744bf3 commit b41b3f5
1 file changed
+8
-4
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
521 | 521 | | |
522 | 522 | | |
523 | 523 | | |
524 | | - | |
525 | | - | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
526 | 528 | | |
527 | 529 | | |
528 | 530 | | |
| |||
739 | 741 | | |
740 | 742 | | |
741 | 743 | | |
742 | | - | |
743 | | - | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
744 | 748 | | |
745 | 749 | | |
746 | 750 | | |
| |||
0 commit comments