authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2022-06-08 14:33:11+02:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2022-06-08 14:33:11+02:00
log33817794268b5453794f98ee752403ff44693112
tree5d869719d15d72fb2e14bfdbe5cf32c46ce091ec
parent61844b6bd405b4cca3ab673284609aa6a651d506
signaturelock-open Commit is signed but in an unrecognized format.

linker: Enable full RELRO by default

Full RELRO is a hardening feature that makes it impossible to perform certian attacks involving overwriting parts of the Global Offset Table to invoke arbitrary code. It requires all symbols to be resolved before execution of the program starts which may have an impact on startup time. However most if not all popular Linux distributions enable full RELRO by default for all binaries and this does not seem to make a noticeable difference in practice. "Partial RELRO" is equivalent to `-z relro -z lazy`. "Full RELRO" is equivalent to `-z relro -z now`. LLD defaults to `-z relro -z lazy`, which means Zig's current `-z relro` option has no effect on LLD's behavior. The changes made by this commit are as follows: - Document that `-z relro` is the default and add `-z norelro`. - Pass `-z now` to LLD by default to enable full RELRO by default. - Add `-z lazy` to disable passing `-z now`.

3 files changed, 21 insertions(+), 11 deletions(-)

src/Compilation.zig+2-2
...@@ -763,8 +763,8 @@ pub const InitOptions = struct {...@@ -763,8 +763,8 @@ pub const InitOptions = struct {
763 linker_z_defs: bool = false,763 linker_z_defs: bool = false,
764 linker_z_origin: bool = false,764 linker_z_origin: bool = false,
765 linker_z_noexecstack: bool = false,765 linker_z_noexecstack: bool = false,
766 linker_z_now: bool = false,766 linker_z_now: bool = true,
767 linker_z_relro: bool = false,767 linker_z_relro: bool = true,
768 linker_z_nocopyreloc: bool = false,768 linker_z_nocopyreloc: bool = false,
769 linker_tsaware: bool = false,769 linker_tsaware: bool = false,
770 linker_nxcompat: bool = false,770 linker_nxcompat: bool = false,
src/link/Elf.zig+5-5
...@@ -1517,12 +1517,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v...@@ -1517,12 +1517,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
1517 try argv.append("noexecstack");1517 try argv.append("noexecstack");
1518 }1518 }
1519 if (self.base.options.z_now) {1519 if (self.base.options.z_now) {
1520 try argv.append("-z");1520 // LLD defaults to -zlazy
1521 try argv.append("now");1521 try argv.append("-znow");
1522 }1522 }
1523 if (self.base.options.z_relro) {1523 if (!self.base.options.z_relro) {
1524 try argv.append("-z");1524 // LLD defaults to -zrelro
1525 try argv.append("relro");1525 try argv.append("-znorelro");
1526 }1526 }
15271527
1528 if (getLDMOption(target)) |ldm| {1528 if (getLDMOption(target)) |ldm| {
src/main.zig+14-4
...@@ -434,8 +434,10 @@ const usage_build_generic =...@@ -434,8 +434,10 @@ const usage_build_generic =
434 \\ origin Indicate that the object must have its origin processed434 \\ origin Indicate that the object must have its origin processed
435 \\ nocopyreloc Disable the creation of copy relocations435 \\ nocopyreloc Disable the creation of copy relocations
436 \\ noexecstack Indicate that the object requires an executable stack436 \\ noexecstack Indicate that the object requires an executable stack
437 \\ now Force all relocations to be processed on load437 \\ now (default) Force all relocations to be processed on load
438 \\ relro Force all relocations to be resolved and be read-only on load438 \\ lazy Don't force all relocations to be processed on load
439 \\ relro (default) Force all relocations to be read-only after processing
440 \\ norelro Don't force all relocations to be read-only after processing
439 \\ -dynamic Force output to be dynamically linked441 \\ -dynamic Force output to be dynamically linked
440 \\ -static Force output to be statically linked442 \\ -static Force output to be statically linked
441 \\ -Bsymbolic Bind global references locally443 \\ -Bsymbolic Bind global references locally
...@@ -655,8 +657,8 @@ fn buildOutputType(...@@ -655,8 +657,8 @@ fn buildOutputType(
655 var linker_z_defs = false;657 var linker_z_defs = false;
656 var linker_z_origin = false;658 var linker_z_origin = false;
657 var linker_z_noexecstack = false;659 var linker_z_noexecstack = false;
658 var linker_z_now = false;660 var linker_z_now = true;
659 var linker_z_relro = false;661 var linker_z_relro = true;
660 var linker_tsaware = false;662 var linker_tsaware = false;
661 var linker_nxcompat = false;663 var linker_nxcompat = false;
662 var linker_dynamicbase = false;664 var linker_dynamicbase = false;
...@@ -1209,8 +1211,12 @@ fn buildOutputType(...@@ -1209,8 +1211,12 @@ fn buildOutputType(
1209 linker_z_noexecstack = true;1211 linker_z_noexecstack = true;
1210 } else if (mem.eql(u8, z_arg, "now")) {1212 } else if (mem.eql(u8, z_arg, "now")) {
1211 linker_z_now = true;1213 linker_z_now = true;
1214 } else if (mem.eql(u8, z_arg, "lazy")) {
1215 linker_z_now = false;
1212 } else if (mem.eql(u8, z_arg, "relro")) {1216 } else if (mem.eql(u8, z_arg, "relro")) {
1213 linker_z_relro = true;1217 linker_z_relro = true;
1218 } else if (mem.eql(u8, z_arg, "norelro")) {
1219 linker_z_relro = false;
1214 } else {1220 } else {
1215 warn("unsupported linker extension flag: -z {s}", .{z_arg});1221 warn("unsupported linker extension flag: -z {s}", .{z_arg});
1216 }1222 }
...@@ -1691,8 +1697,12 @@ fn buildOutputType(...@@ -1691,8 +1697,12 @@ fn buildOutputType(
1691 linker_z_noexecstack = true;1697 linker_z_noexecstack = true;
1692 } else if (mem.eql(u8, z_arg, "now")) {1698 } else if (mem.eql(u8, z_arg, "now")) {
1693 linker_z_now = true;1699 linker_z_now = true;
1700 } else if (mem.eql(u8, z_arg, "lazy")) {
1701 linker_z_now = false;
1694 } else if (mem.eql(u8, z_arg, "relro")) {1702 } else if (mem.eql(u8, z_arg, "relro")) {
1695 linker_z_relro = true;1703 linker_z_relro = true;
1704 } else if (mem.eql(u8, z_arg, "norelro")) {
1705 linker_z_relro = false;
1696 } else {1706 } else {
1697 warn("unsupported linker extension flag: -z {s}", .{z_arg});1707 warn("unsupported linker extension flag: -z {s}", .{z_arg});
1698 }1708 }