Fix overflow for timeout values of more than 68 years, which is the maximum
covered by sbintime (LONG_MAX seconds). Some programs use timeout values in excess of 1000 years. The conversion to sbintime caused wrap-around on overflow, which resulted in short or negative timeout values. This caused long delays on sockets opened by affected programs (e.g. OpenSSH). Kernels compiled without -fno-strict-overflow were not affected, apparently because the compiler tested the sign of the timeout value before performing the multiplication that lead to overflow. When the -fno-strict-overflow option was added to CFLAGS, this optimization was disabled and the test was performed on the result of the multiplication. Negative products were caught and resulted in EINVAL being returned, but wrap-around to positive values just shortened the timeout value to the residue of the result that could be represented by sbintime. The fix is to cap the timeout values at the maximum that can be represented by sbintime, which is 2^31 - 1 seconds or more than 68 years. After this change, the kernel can be compiled with -fno-strict-overflow with no ill effects. MFC after: 3 days
This commit is contained in:
parent
6311cc9efe
commit
53d5cc255d
@ -526,7 +526,8 @@ knote_fork(struct knlist *list, int pid)
|
||||
static __inline sbintime_t
|
||||
timer2sbintime(intptr_t data)
|
||||
{
|
||||
|
||||
if (data > LLONG_MAX / SBT_1MS)
|
||||
return LLONG_MAX;
|
||||
return (SBT_1MS * data);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user