Index | Thread | Search

From:
Leah Rowe <info@minifree.org>
Subject:
Re: mozilla port hardening, part II
To:
"ports@openbsd.org" <ports@openbsd.org>
Date:
Tue, 8 Sep 2026 11:39:48 +0100

Download raw body.

Thread
hi

because i'm bored, i actually checked inside firefox.git

i see landry added --enable-rust-simd, without making it a toggle, just 
made it universally enabled on all mozilla ports. the patch omitted the 
other two options.

i previously just read some mozilla documentation, but this time i 
specifically read build/moz.configure/toolchain.configure in firefox.git 
at git tag for 155.0.1 and found:


     if using_msvc_stl_202503_or_newer:
         return ["-D_MSVC_STL_HARDENING=1"]
     if using_libstdcxx:
         return ["-D_GLIBCXX_ASSERTIONS=1"]
     if using_libcxx:
         if using_libcxx_19_or_newer:
             if debug:
                 return 
["-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG"]
             else:
                 return 
["-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE"]
         else:
             return ["-D_LIBCPP_ENABLE_ASSERTIONS=1"]


that's what i found for --enable-stl-hardening, above. looks like 
therefore we would typically get:  return 
["-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE"]


as for --enable-hardening, i see:

         if compiler_is_gccish and not asan:
             flags.append("-fstack-protector-strong")
             ldflags.append("-fstack-protector-strong")

             if (
                 c_compiler.type == "clang"
                 and target.os not in ("WINNT", "OSX", "OpenBSD", "iOS")
                 and ((c_compiler.version >= "11.0.1" and target.cpu in 
("x86", "x86_64", "ppc64", "s390x"))
                     or
                      (c_compiler.version >= "18.1.0" and target.cpu == 
"aarch64"))
             ):
                 flags.append("-fstack-clash-protection")
                 ldflags.append("-fstack-clash-protection")

NOTE: in our context, llvm/clang/etc is indeed "gccish"

         linux32 = target.kernel == "Linux" and target.cpu == "x86"
         if (
             (c_compiler.type == "clang" or c_compiler.type == "clang-cl")
             and c_compiler.version >= "8"
             and not linux32
         ):
             if c_compiler.type == "clang-cl":
                 trivial_auto_var_init.append("-Xclang")
trivial_auto_var_init.append("-ftrivial-auto-var-init=pattern")

^ note that librewolf (port) already sets -ftrivial-auto-var-init=zero, 
so i guess that's harder than the above (pattern)

         if (c_compiler.type == "clang" and c_compiler.version >= "16") or (
             c_compiler.type == "gcc" and c_compiler.version >= "13"
         ):
             # Cannot use level 3 because we have many uses of the [0] 
GNU syntax.
             # Cannot use level 2 because sqlite3 and icu use the [1] 
GNU syntax.
             flags.append("-fstrict-flex-arrays=1")


         # Control Flow Guard (CFG) ----------------------------
         if (
             c_compiler.type == "clang-cl"
             and c_compiler.version >= "8"
             and (target.cpu != "aarch64" or c_compiler.version >= "8.0.1")
         ):
             if target.cpu == "aarch64" and c_compiler.version >= "10.0.0":
                 # The added checks in clang 10 make arm64 builds crash. 
(Bug 1639318)
                 flags.append("-guard:cf,nochecks")
             else:
                 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")

     # If ASAN _is_ on, disable FORTIFY_SOURCE just to be safe
     if asan:
         flags.append("-D_FORTIFY_SOURCE=0")

     # 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
         if c_compiler.type == "clang-cl":
             flags.append("-Xclang")
         flags.append("-fno-common")

     return namespace(
         flags=flags,
         ldflags=ldflags,
         trivial_auto_var_init=trivial_auto_var_init,
     )


I've no idea if asan is turned on, but from the above, I can see that in 
OpenBSD we would get with --enable-hardening, the following flags added:

(I will assume that asan is turned off):

-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -- i'm told this is useless on 
openbsd. we also get:

-fstack-protector-strong -fstack-clash-protection <-- removed if ASAN 
turned on. then (regardless): -ftrivial-auto-var-init=pattern 
-fstrict-flex-arrays=1

ldflags: -fstack-protector-strong -fstack-clash-protection <-- removed 
if ASAN turn on. then: -Wl,--dynamicbase -guard:cf,nolongjmp

on arm64 we get the following CFLAG added: -guard:cf,nochecks - and on 
everything else, we get: -guard:cf


for --enable-stl-hardening, used on C++ code, we would get these added: 
-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE (for libcpp 
older than 19 we get instead: -D_LIBCPP_ENABLE_ASSERTIONS=1)


my judgement is as i was told earlier, that these two options are 
basically redundant on OpenBSD, but some of the above options might be 
worthwhile adding on their own. Look at 
build/moz.configure/toolchain.configure in firefox source tree to see 
exactly what these options add.

that's actually really nice, the way mozilla configures that. pretty 
much all the flags are easy to figure out from that file.



Am 05.09.26 um 19:29 schrieb Leah Rowe:
>
> tl;dr the patch is still garbage. stl-hardening option though is 
> useful, and i don't think openbsd otherwise compensates for it being 
> missing; it might be worth turning on. i haven't checked whether 
> mozilla's codebases turns it on by default, but adding it can't hurt.
>
> logically, i consider that if stl-hardening is present, then the 
> normal hardening option might be as well, but i think probably it 
> might be better to just directly audit the various mozilla build 
> systems (thunderbird, firefox, seamonkey, tor browser) to see exactly 
> what these options enable, and i mean surgically. and then add any of 
> those to openbsd as desired, rather than --enable-hardening; this is 
> because it's quite possible that --enable-hardening might be enabling 
> options that reduce security, if openbsd is already being strict about 
> that (via its modifications to llvm).
>
> mach build system is just a mess in general imo. honestly, i'd just 
> ignore the patch, if i were you. i'm just being thorough by sending 
> it. merge it or don't :)
>
>
> Am 05.09.26 um 17:11 schrieb Leah Rowe:
>> Hi everyone!
>>
>> Here is a new version of the hardening patch I sent earlier, after 
>> feedback on the original version. This adds the following options to 
>> mozilla ports, where available:
>>
>> --enable-hardening
>>
>> --enable-stl-hardening
>>
>> --enable-rust-simd
>>
>> the rust simd and stl hardening options can be toggled, in this new 
>> patch. i suppose a toggle could be added for --enable-hardening, but 
>> i didn't bother
>>
>> Pros and cons of each is written inside the patch. I'll just paste 
>> here what's written in my patch:
>>
>>     enable hardening flags in mozilla projects
>>
>>     there is also a rust-sized easter egg.
>>
>>     --enable-hardening appends these flags to CFLAGS, CXXFLAGS and 
>> LDFLAGS at
>>     build time:
>>     * -fstack-protector-strong or -fstack-protector-all depending on 
>> target
>>     * -D_FORTIFY_SOURCE=2 - useless on openbsd
>>     * fPIE - redundant here (forced by default on openbsd llvm/gcc)
>>     * -Wl,-z,relro/now: redundant on openbsd
>>     * -ftrapv or -fno-strict-overflow: treat signed integer overflow 
>> as UB
>>
>>     OpenBSD will already do this by default, so this option is likely 
>> redundant,
>>     but ensures that Mozilla's build system will not *clear* any such 
>> flags.
>>
>>     --enable-stl-hardening turns on safe mode and assertions inside 
>> the C++
>>     standard template library (STL) and catched out of bound 
>> array/vector indexing,
>>     iterator invalidation, null-pointer deref in stl containsers, and 
>> invalid
>>     ranges at runtime, mitigating them before they can be exploited. 
>> specifically
>>     enables these flags:
>>     * for clang using libc++:
>>      * -D_LIBCPP_ENABLE_HARDENED_MODE=1
>>      * runtime bounds checks on std::vector::operator[], std::string,
>>        std::optional, std::variants and iterator bounds checking
>>
>>     Enabling --enable-stl-hardening forces LLVM's libc++ to abort 
>> immediately
>>     if an STL container boundary violation occurs, e.g. calling
>>     std::vector::operator out of range. This mitigates errors 
>> pertaining to
>>     heap corruption, though OpenBSD will already do something for 
>> this at
>>     kernel level, e.g. pledge is basically the best thing ever.
>>
>>     --enable-rust-simd is an interesting one:
>>     It can improve performance in some workloads by processing text, 
>> data
>>     and images using hardware acceleration (simd) depending on the 
>> machine.
>>     This can cause massive throughput gains in e.g. encoding_rs when 
>> decoding
>>     web pages (converting raw html/js byte streams into utf/8/16). 
>> Normally,
>>     html/js markup contain a lot of ascii, and so you have 
>> ascii/utf-8 validation;
>>     with the simd extension enabled, your browser processes text e.g. 
>> 16 or 32
>>     bytes at a time instead of 1 byte at a time, via hardware features
>>     like sse/avx or neon. It's unknown whether this might negatively 
>> impact older
>>     systems, but this would have to be tested over time.
>>
>>     image/media processing: lots of this in gecko now are written in 
>> rust, e.g.
>>     png/jpg decoding, colour profile transformation, audio 
>> re-sampling. simd
>>     lets rust run identical operations e.g. alpha blending, byte 
>> swapping, colour
>>     conversion across entire blocks of pixels in a single cpu cycle, 
>> instead of
>>     doing everything in software. this obviously depends on the 
>> user's machine.
>>
>>     faster cryptography/hashing: rust crates used for crypto, https 
>> handshakes,
>>     and internal structures e.g. fash hash tables, can use simd for 
>> parallel
>>     bitwise operations and byte shifts, reducing cpu overhead when 
>> negotiating
>>     connections and such.
>>
>>     Risks associated with --enable-rust-simd:
>>
>>     This turns on RUSTC_BOOTSTRAP=1. Despite the name, this doesn't 
>> cause anything
>>     to be downloaded, but it does allow certain nightly features to 
>> be used
>>     in Rust, that have not yet been declared stable. Turning this 
>> option on will
>>     bypass compiler safety checks to use experimental features, that 
>> may break
>>     after updates (e.g. newer rustc/cargo on older mozilla codebase; 
>> disabling
>>     simd on firefox/thunderbird ESR releases might be prudent). 
>> obviously this
>>     means that code generation might be a bit buggier, potentially 
>> leading to
>>     some UB. without this option enabled, rustc will be much more 
>> conservative,
>>     only generating code that will run on virtually any CPU. one of 
>> the downsides
>>     doesn't apply to openbsd: this option makes cross compilation 
>> less reliable,
>>     but openbsd doesn't use cross compilation anyway.
>>
>>     enable hardening flags in mozilla projects
>>
>>     there is also a rust-sized easter egg.
>>
>>     --enable-hardening appends these flags to CFLAGS, CXXFLAGS and 
>> LDFLAGS at
>>     build time:
>>     * -fstack-protector-strong or -fstack-protector-all depending on 
>> target
>>     * -D_FORTIFY_SOURCE=2 - useless on openbsd
>>     * fPIE - redundant here (forced by default on openbsd llvm/gcc)
>>     * -Wl,-z,relro/now: redundant on openbsd
>>     * -ftrapv or -fno-strict-overflow: treat signed integer overflow 
>> as UB
>>
>>     OpenBSD will already do this by default, so this option is likely 
>> redundant,
>>     but ensures that Mozilla's build system will not *clear* any such 
>> flags.
>>
>>     --enable-stl-hardening turns on safe mode and assertions inside 
>> the C++
>>     standard template library (STL) and catched out of bound 
>> array/vector indexing,
>>     iterator invalidation, null-pointer deref in stl containsers, and 
>> invalid
>>     ranges at runtime, mitigating them before they can be exploited. 
>> specifically
>>     enables these flags:
>>     * for clang using libc++:
>>      * -D_LIBCPP_ENABLE_HARDENED_MODE=1
>>      * runtime bounds checks on std::vector::operator[], std::string,
>>        std::optional, std::variants and iterator bounds checking
>>
>>     Enabling --enable-stl-hardening forces LLVM's libc++ to abort 
>> immediately
>>     if an STL container boundary violation occurs, e.g. calling
>>     std::vector::operator out of range. This mitigates errors 
>> pertaining to
>>     heap corruption, though OpenBSD will already do something for 
>> this at
>>     kernel level, e.g. pledge is basically the best thing ever.
>>
>>     --enable-rust-simd is an interesting one:
>>     It can improve performance in some workloads by processing text, 
>> data
>>     and images using hardware acceleration (simd) depending on the 
>> machine.
>>     This can cause massive throughput gains in e.g. encoding_rs when 
>> decoding
>>     web pages (converting raw html/js byte streams into utf/8/16). 
>> Normally,
>>     html/js markup contain a lot of ascii, and so you have 
>> ascii/utf-8 validation;
>>     with the simd extension enabled, your browser processes text e.g. 
>> 16 or 32
>>     bytes at a time instead of 1 byte at a time, via hardware features
>>     like sse/avx or neon. It's unknown whether this might negatively 
>> impact older
>>     systems, but this would have to be tested over time.
>>
>>     image/media processing: lots of this in gecko now are written in 
>> rust, e.g.
>>     png/jpg decoding, colour profile transformation, audio 
>> re-sampling. simd
>>     lets rust run identical operations e.g. alpha blending, byte 
>> swapping, colour
>>     conversion across entire blocks of pixels in a single cpu cycle, 
>> instead of
>>     doing everything in software. this obviously depends on the 
>> user's machine.
>>
>>     faster cryptography/hashing: rust crates used for crypto, https 
>> handshakes,
>>     and internal structures e.g. fash hash tables, can use simd for 
>> parallel
>>     bitwise operations and byte shifts, reducing cpu overhead when 
>> negotiating
>>     connections and such.
>>
>>     Risks associated with --enable-rust-simd:
>>
>>     This turns on RUSTC_BOOTSTRAP=1. Despite the name, this doesn't 
>> cause anything
>>     to be downloaded, but it does allow certain nightly features to 
>> be used
>>     in Rust, that have not yet been declared stable. Turning this 
>> option on will
>>     bypass compiler safety checks to use experimental features, that 
>> may break
>>     after updates (e.g. newer rustc/cargo on older mozilla codebase; 
>> disabling
>>     simd on firefox/thunderbird ESR releases might be prudent). 
>> obviously this
>>     means that code generation might be a bit buggier, potentially 
>> leading to
>>     some UB. without this option enabled, rustc will be much more 
>> conservative,
>>     only generating code that will run on virtually any CPU. one of 
>> the downsides
>>     doesn't apply to openbsd: this option makes cross compilation 
>> less reliable,
>>     but openbsd doesn't use cross compilation anyway.
>>
-- 
Company director, Minifree Ltd
Registered in England, No. 9361826 | VAT No. GB202190462
Registered Office: 19 Hilton Road, Canvey Island, Essex SS8 9QA, UK