[lld] daba24e - [ELF] << >>: make RHS less than 64

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 15 10:34:38 PDT 2023


Author: Fangrui Song
Date: 2023-06-15T10:34:33-07:00
New Revision: daba24ee7bd3d80f085e2e5f057af6b873a78a24

URL: https://github.com/llvm/llvm-project/commit/daba24ee7bd3d80f085e2e5f057af6b873a78a24
DIFF: https://github.com/llvm/llvm-project/commit/daba24ee7bd3d80f085e2e5f057af6b873a78a24.diff

LOG: [ELF] << >>: make RHS less than 64

The left/right shift linker script operators may trigger UB.
E.g. in linkerscript/end-overflow-check.test, the initial REGION1__PADDED_SR_SHIFT is
uint64_t(-3), cause the following expression to trigger an out-of-range shift in
a ubsan build of lld.

    REGION1__PADDED_SR_SIZE = MAX(1 << REGION1__PADDED_SR_SHIFT, 32);

Protect such UBs by making RHS less than 64.

Added: 
    

Modified: 
    lld/ELF/ScriptParser.cpp
    lld/test/ELF/linkerscript/operators.test

Removed: 
    


################################################################################
diff  --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index a4fb0f7c6e17c..85cee08999cd3 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -1094,9 +1094,9 @@ SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
       case '-':
         return sub(lhs, e());
       case '<':
-        return lhs.getValue() << e().getValue();
+        return lhs.getValue() << e().getValue() % 64;
       case '>':
-        return lhs.getValue() >> e().getValue();
+        return lhs.getValue() >> e().getValue() % 64;
       case '&':
         return lhs.getValue() & e().getValue();
       case '|':
@@ -1147,9 +1147,9 @@ Expr ScriptParser::combine(StringRef op, Expr l, Expr r) {
     };
   }
   if (op == "<<")
-    return [=] { return l().getValue() << r().getValue(); };
+    return [=] { return l().getValue() << r().getValue() % 64; };
   if (op == ">>")
-    return [=] { return l().getValue() >> r().getValue(); };
+    return [=] { return l().getValue() >> r().getValue() % 64; };
   if (op == "<")
     return [=] { return l().getValue() < r().getValue(); };
   if (op == ">")

diff  --git a/lld/test/ELF/linkerscript/operators.test b/lld/test/ELF/linkerscript/operators.test
index 3958b956a8eb5..0b6fdc2fe63f8 100644
--- a/lld/test/ELF/linkerscript/operators.test
+++ b/lld/test/ELF/linkerscript/operators.test
@@ -12,6 +12,7 @@ SECTIONS {
   multiplicative = 20 / 2 % 7;
   additive = 1 - 2 + -3 * -2;
   shift = 2 << 5 >> 1 << 2;
+  shift2 = 2 << 69 >> 65;
   less = 1 < 0 ? 1 : 2;
   lesseq = 1<<0 <= 1>>0 ? 1 : 2;
   greater = 0 > 1 ? 1 : 2;
@@ -36,9 +37,11 @@ SECTIONS {
   minusassign = 3;
   minusassign -= 1;
   lshiftassign = 1;
-  lshiftassign <<= 2;
-  rshiftassign = 5;
+  lshiftassign <<= 1;
+  lshiftassign <<= 65;  # arbitrarily reduced to 1
+  rshiftassign = 24;
   rshiftassign >>= 1;
+  rshiftassign >>= 130;  # arbitrarily reduced to 2
   andassign = 6;
   andassign &= 4;
   orassign = 4;
@@ -73,6 +76,7 @@ SECTIONS {
 # CHECK-NEXT: 0000000000000003 A multiplicative
 # CHECK-NEXT: 0000000000000005 A additive
 # CHECK-NEXT: 0000000000000080 A shift
+# CHECK-NEXT: 0000000000000020 A shift
 # CHECK-NEXT: 0000000000000002 A less
 # CHECK-NEXT: 0000000000000001 A lesseq
 # CHECK-NEXT: 0000000000000002 A greater
@@ -92,7 +96,7 @@ SECTIONS {
 # CHECK-NEXT: 0000000000000003 A plusassign
 # CHECK-NEXT: 0000000000000002 A minusassign
 # CHECK-NEXT: 0000000000000004 A lshiftassign
-# CHECK-NEXT: 0000000000000002 A rshiftassign
+# CHECK-NEXT: 0000000000000003 A rshiftassign
 # CHECK-NEXT: 0000000000000004 A andassign
 # CHECK-NEXT: 0000000000000005 A orassign
 # CHECK-NEXT: 0000000000000015 A braces


        


More information about the llvm-commits mailing list