[Git][ghc/ghc][ghc-8.8] rts/linker: Fix relocation overflow in PE linker
Ben Gamari
gitlab at gitlab.haskell.org
Sat Nov 14 11:49:14 UTC 2020
Ben Gamari pushed to branch ghc-8.8 at Glasgow Haskell Compiler / GHC
Commits:
c58498b2 by Ben Gamari at 2020-11-14T06:49:01-05:00
rts/linker: Fix relocation overflow in PE linker
Previously the overflow check for the IMAGE_REL_AMD64_ADDR32NB
relocation failed to account for the signed nature of the value.
Specifically, the overflow check was:
uint64_t v;
v = S + A;
if (v >> 32) { ... }
However, `v` ultimately needs to fit into 32-bits as a signed value.
Consequently, values `v > 2^31` in fact overflow yet this is not caught
by the existing overflow check.
Here we rewrite the overflow check to rather ensure that
`INT32_MIN <= v <= INT32_MAX`. There is now quite a bit of repetition
between the `IMAGE_REL_AMD64_REL32` and `IMAGE_REL_AMD64_ADDR32` cases
but I am leaving fixing this for future work.
This bug was first noticed by @awson.
Fixes #15808.
(cherry picked from commit 6d21ecee535782f01dba9947a49e282afee25724)
- - - - -
2 changed files:
- libraries/Cabal
- rts/linker/PEi386.c
Changes:
=====================================
libraries/Cabal
=====================================
@@ -1 +1 @@
-Subproject commit 8199c3f838a15fb9b7c8d3527603084b2474d877
+Subproject commit bd07f0a095869b91a590d8a564f716a6a136818a
=====================================
rts/linker/PEi386.c
=====================================
@@ -1943,13 +1943,15 @@ ocResolve_PEi386 ( ObjectCode* oc )
{
uint64_t v;
v = S + A;
- if (v >> 32) {
+ // N.B. in the case of the sign-extended relocations we must ensure that v
+ // fits in a signed 32-bit value. See #15808.
+ if (((int64_t) v > (int64_t) INT32_MAX) || ((int64_t) v < (int64_t) INT32_MIN)) {
copyName (getSymShortName (info, sym), oc,
symbol, sizeof(symbol)-1);
S = makeSymbolExtra_PEi386(oc, symIndex, S, (char *)symbol);
/* And retry */
v = S + A;
- if (v >> 32) {
+ if (((int64_t) v > (int64_t) INT32_MAX) || ((int64_t) v < (int64_t) INT32_MIN)) {
barf("IMAGE_REL_AMD64_ADDR32[NB]: High bits are set in %zx for %s",
v, (char *)symbol);
}
@@ -1961,14 +1963,14 @@ ocResolve_PEi386 ( ObjectCode* oc )
{
intptr_t v;
v = S + (int32_t)A - ((intptr_t)pP) - 4;
- if ((v > (intptr_t) INT32_MAX) || (v < (intptr_t) INT32_MIN)) {
+ if ((v > (int64_t) INT32_MAX) || (v < (int64_t) INT32_MIN)) {
/* Make the trampoline then */
copyName (getSymShortName (info, sym),
oc, symbol, sizeof(symbol)-1);
S = makeSymbolExtra_PEi386(oc, symIndex, S, (char *)symbol);
/* And retry */
v = S + (int32_t)A - ((intptr_t)pP) - 4;
- if ((v > (intptr_t) INT32_MAX) || (v < (intptr_t) INT32_MIN)) {
+ if ((v > (int64_t) INT32_MAX) || (v < (int64_t) INT32_MIN)) {
barf("IMAGE_REL_AMD64_REL32: High bits are set in %zx for %s",
v, (char *)symbol);
}
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c58498b2dd95bac99cb3fa9014fa64cf12dd2f18
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c58498b2dd95bac99cb3fa9014fa64cf12dd2f18
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20201114/5058a461/attachment-0001.html>
More information about the ghc-commits
mailing list