Laszlo Ersek 75505d1611 MdePkg/BaseSafeIntLib: fix undefined behavior in SafeInt64Mult()
If we have to negate UnsignedResult (due to exactly one of Multiplicand
and Multiplier being negative), and UnsignedResult is exactly
MIN_INT64_MAGNITUDE (value 2^63), then the statement

        *Result = - ((INT64)UnsignedResult);

invokes both implementation-defined behavior and undefined behavior.

First, MIN_INT64_MAGNITUDE is not representable as INT64, therefore the
result of the (inner) conversion

  (INT64)MIN_INT64_MAGNITUDE

is implementation-defined, or an implementation-defined signal is raised,
according to ISO C99 6.3.1.3p3.

Second, if we assume that the C language implementation defines the
conversion to INT64 simply as reinterpreting the bit pattern
0x8000_0000_0000_0000 as a signed integer in two's complement
representation, then the conversion immediately produces the negative
value MIN_INT64 (value -(2^63)). In turn, the (outer) negation

  -(MIN_INT64)

invokes undefined behavior, because the mathematical result of the
negation, namely 2^63, cannot be represented in an INT64 object. (Not even
mentioning the fact that the mathematical result would be incorrect.) In
practice, the undefined negation of MIN_INT64 happens to produce an
unchanged, valid-looking result on x86, i.e. (-(MIN_INT64)) == MIN_INT64.

We can summarize this as the undefined -- effectless -- negation canceling
out the botched -- auto-negating -- implementation-defined conversion.
Instead of relying on such behavior, dedicate a branch to this situation:
assign MIN_INT64 directly. The branch can be triggered e.g. by multiplying
(2^62) by (-2).

Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Michael D Kinney <michael.d.kinney@intel.com>
2018-02-21 11:57:39 +01:00
2018-02-10 19:55:13 +08:00
2014-10-14 16:08:15 +00:00

EDK II Project

A modern, feature-rich, cross-platform firmware development environment for the UEFI and PI specifications from www.uefi.org.

Contributions to the EDK II open source project are covered by the TianoCore Contribution Agreement 1.1

The majority of the content in the EDK II open source project uses a BSD 2-Clause License. The EDK II open source project contains the following components that are covered by additional licenses:

The EDK II Project is composed of packages. The maintainers for each package are listed in Maintainers.txt.

Resources

Description
Acidanthera UEFI Development Kit based on EDK II edk2-stable202405
Readme 330 MiB
Languages
C 71.6%
Assembly 16.4%
Python 8.5%
Rich Text Format 1.3%
C++ 0.8%
Other 1%