mirror of https://github.com/acidanthera/audk.git
UefiCpuPkg/MpLib: fix potential overflow issue.
Current calculate timeout logic may have overflow if the input timeout value too large. This patch fix this potential overflow issue. V2: Use local variable instead of call GetPerformanceCounterProperties twice. Also correct some comments. Cc: Michael Kinney <michael.d.kinney@intel.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Eric Dong <eric.dong@intel.com> Reviewed-by: Michael Kinney <michael.d.kinney@intel.com>
This commit is contained in:
parent
714c260301
commit
48cfb7c0f4
|
@ -1001,6 +1001,9 @@ CalculateTimeout (
|
|||
OUT UINT64 *CurrentTime
|
||||
)
|
||||
{
|
||||
UINT64 TimeoutInSeconds;
|
||||
UINT64 TimestampCounterFreq;
|
||||
|
||||
//
|
||||
// Read the current value of the performance counter
|
||||
//
|
||||
|
@ -1016,17 +1019,37 @@ CalculateTimeout (
|
|||
|
||||
//
|
||||
// GetPerformanceCounterProperties () returns the timestamp counter's frequency
|
||||
// in Hz. So multiply the return value with TimeoutInMicroseconds and then divide
|
||||
// in Hz.
|
||||
//
|
||||
TimestampCounterFreq = GetPerformanceCounterProperties (NULL, NULL);
|
||||
|
||||
//
|
||||
// Check the potential overflow before calculate the number of ticks for the timeout value.
|
||||
//
|
||||
if (DivU64x64Remainder (MAX_UINT64, TimeoutInMicroseconds, NULL) < TimestampCounterFreq) {
|
||||
//
|
||||
// Convert microseconds into seconds if direct multiplication overflows
|
||||
//
|
||||
TimeoutInSeconds = DivU64x32 (TimeoutInMicroseconds, 1000000);
|
||||
//
|
||||
// Assertion if the final tick count exceeds MAX_UINT64
|
||||
//
|
||||
ASSERT (DivU64x64Remainder (MAX_UINT64, TimeoutInSeconds, NULL) >= TimestampCounterFreq);
|
||||
return MultU64x64 (TimestampCounterFreq, TimeoutInSeconds);
|
||||
} else {
|
||||
//
|
||||
// No overflow case, multiply the return value with TimeoutInMicroseconds and then divide
|
||||
// it by 1,000,000, to get the number of ticks for the timeout value.
|
||||
//
|
||||
return DivU64x32 (
|
||||
MultU64x64 (
|
||||
GetPerformanceCounterProperties (NULL, NULL),
|
||||
TimestampCounterFreq,
|
||||
TimeoutInMicroseconds
|
||||
),
|
||||
1000000
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Checks whether timeout expires.
|
||||
|
|
Loading…
Reference in New Issue