Skip to content

Commit b41b3f5

Browse files
tomerdbzgalnoam
authored andcommitted
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

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

tests/gtest/udp/udp_send.cc

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -521,8 +521,10 @@ TEST_F(udp_send, null_iov_elements)
521521
break;
522522
}
523523

524-
received += static_cast<size_t>(rc);
525-
log_trace("Received %zd\n", received);
524+
if (rc > 0) {
525+
received += static_cast<size_t>(rc);
526+
log_trace("Received %zd\n", received);
527+
}
526528
}
527529

528530
log_trace("Received Final %zd\n", received);
@@ -739,8 +741,10 @@ TEST_F(udp_send, DISABLED_null_iov_elements_fragmented)
739741
break;
740742
}
741743

742-
received += static_cast<size_t>(rc);
743-
log_trace("Received %d\n", rc);
744+
if (rc > 0) {
745+
received += static_cast<size_t>(rc);
746+
log_trace("Received %d\n", rc);
747+
}
744748
}
745749

746750
log_trace("Received Final %zd\n", received);

0 commit comments

Comments
 (0)