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
|
OUT UINT64 *CurrentTime
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
UINT64 TimeoutInSeconds;
|
||||||
|
UINT64 TimestampCounterFreq;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Read the current value of the performance counter
|
// Read the current value of the performance counter
|
||||||
//
|
//
|
||||||
|
@ -1016,16 +1019,36 @@ CalculateTimeout (
|
||||||
|
|
||||||
//
|
//
|
||||||
// GetPerformanceCounterProperties () returns the timestamp counter's frequency
|
// GetPerformanceCounterProperties () returns the timestamp counter's frequency
|
||||||
// in Hz. So multiply the return value with TimeoutInMicroseconds and then divide
|
// in Hz.
|
||||||
// it by 1,000,000, to get the number of ticks for the timeout value.
|
|
||||||
//
|
//
|
||||||
return DivU64x32 (
|
TimestampCounterFreq = GetPerformanceCounterProperties (NULL, NULL);
|
||||||
MultU64x64 (
|
|
||||||
GetPerformanceCounterProperties (NULL, NULL),
|
//
|
||||||
TimeoutInMicroseconds
|
// Check the potential overflow before calculate the number of ticks for the timeout value.
|
||||||
),
|
//
|
||||||
1000000
|
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 (
|
||||||
|
TimestampCounterFreq,
|
||||||
|
TimeoutInMicroseconds
|
||||||
|
),
|
||||||
|
1000000
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue