Bug 1485016 - Enable CFG for Windows builds r=dmajor a=lizzard
authorTom Ritter <tom@mozilla.com>
Fri, 25 Jan 2019 10:41:27 -0600
changeset 515846 0456b8fcad6f14cc862d3428b3f42644c40a850b
parent 515845 fe8f0e01fc952e240a0ea4eb2799d2181abf2514
child 515847 76698f80b156046fab7d43d6517dddc95a702bc6
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdmajor, lizzard
bugs1485016
milestone66.0
Bug 1485016 - Enable CFG for Windows builds r=dmajor a=lizzard
build/moz.configure/toolchain.configure
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -1657,26 +1657,36 @@ add_old_configure_assignment('MOZ_UBSAN_
 
 # Security Hardening
 # ==============================================================
 
 option('--enable-hardening', env='MOZ_SECURITY_HARDENING',
        help='Enables security hardening compiler options')
 
 
+# This function is a bit confusing. It adds or removes hardening flags in
+# three stuations: if --enable-hardening is passed; if --disable-hardening
+# is passed, and if no flag is passed.
+#
+# At time of this comment writing, all flags are actually added in the
+# default no-flag case; making --enable-hardening the same as omitting the
+# flag. --disable-hardening will omit the security flags. (However, not all
+# possible security flags will be omitted by --disable-hardening, as many are
+# compiler-default options we do not explicitly enable.)
 @depends('--enable-hardening', '--enable-address-sanitizer',
          '--enable-optimize', c_compiler, target)
 def security_hardening_cflags(hardening_flag, asan, optimize, c_compiler, target):
     compiler_is_gccish = c_compiler.type in ('gcc', 'clang')
 
     flags = []
     ldflags = []
     js_flags = []
     js_ldflags = []
 
+    # ----------------------------------------------------------
     # If hardening is explicitly enabled, or not explicitly disabled
     if hardening_flag.origin == "default" or hardening_flag:
         # FORTIFY_SOURCE ------------------------------------
         # Require optimization for FORTIFY_SOURCE. See Bug 1417452
         # Also, undefine it before defining it just in case a distro adds it, see Bug 1418398
         if compiler_is_gccish and optimize and not asan:
             # Don't enable FORTIFY_SOURCE on Android on the top-level, but do enable in js/
             if target.os != 'Android':
@@ -1695,17 +1705,27 @@ def security_hardening_cflags(hardening_
 
         # ASLR ------------------------------------------------
         # ASLR (dynamicbase) is enabled by default in clang-cl; but the
         # mingw-clang build requires it to be explicitly enabled
         if target.os == 'WINNT' and c_compiler.type == 'clang':
             ldflags.append("-Wl,--dynamicbase")
             js_ldflags.append("-Wl,--dynamicbase")
 
-    # If ASAN _is_ on, undefine FOTIFY_SOURCE just to be safe
+        # Control Flow Guard (CFG) ----------------------------
+        if c_compiler.type == 'clang-cl' and c_compiler.version >= '8':
+            flags.append("-guard:cf")
+            js_flags.append("-guard:cf")
+            # nolongjmp is needed because clang doesn't emit the CFG tables of
+            # setjmp return addresses https://bugs.llvm.org/show_bug.cgi?id=40057
+            ldflags.append("-guard:cf,nolongjmp")
+            js_ldflags.append("-guard:cf,nolongjmp")
+
+    # ----------------------------------------------------------
+    # If ASAN _is_ on, undefine FORTIFY_SOURCE just to be safe
     if asan:
         flags.append("-U_FORTIFY_SOURCE")
         js_flags.append("-U_FORTIFY_SOURCE")
 
     # fno-common -----------------------------------------
     # Do not merge variables for ASAN; can detect some subtle bugs
     if asan:
         # clang-cl does not recognize the flag, it must be passed down to clang