rust icon indicating copy to clipboard operation
rust copied to clipboard

sess: stabilize `-Zrelro-level` as `-Crelro-level`

Open davidtwco opened this issue 11 months ago • 9 comments

Stabilise -Zrelro-level as -Crelro-level. There's no tracking issue for this flag to close.

davidtwco avatar Feb 27 '24 17:02 davidtwco

Stabilization report

RELRO (Relocation Read-Only) is a binary hardening technique, it makes the Global Offset Table (GOT) read-only (preventing some avenues of exploitation).

Roughly speaking, calls to functions from dynamic libraries are implemented using the Global Offset Table (GOT) and Procedure Linking Table (PLT) in an ELF file. A call to foo from a foreign library is codegen'd to a call into a stub in the PLT, foo@plt, which looks up the GOT for the real address of foo. If this is the first time that foo has been called, then that won't be known, and the fallback stub's address will be in the GOT and that will be jumped to instead. The fallback handler calls into ld.so to resolve the function and then writes its address into the GOT. Subsequent calls to foo@plt will just jump straight to foo.

This scheme necessitates that the GOT is writable, which opens up the possibility for exploitation. Full RELRO resolves all the function addresses when the program is initially loaded and populates the GOT eagerly - this uses more memory and increases process startup time - but it allows the GOT to be made read-only (both .got and .got.plt). Partial RELRO only makes the non-PLT part of the GOT read-only (.got), but .got.plt is still writable. Both partial and full RELRO re-order sections to protect them from being written by buffer overflows.

rustc allows configuration of RELRO levels with -Zrelro-level={off,partial,full} and if this isn't set, then each target can set a default RELRO level. We enable full RELRO on many of our targets by default (e.g. Linux, BSD, etc).

This feature has been implemented since 2017 and has been enabled by default for most platforms on which it is enabled since that initial implementation.

If we don't enable RELRO by default on a target, then users have no way of requesting it on stable toolchains. If RELRO is undesirable, then users have no way of disabling it on stable toolchains.

As per other platform-specific codegen flags, this option is ignored on those targets (e.g. like -Ccontrol-flow-guard on non-Windows targets).

Tests

History

  • rust-lang/rust#43170 (initial implementation)
  • rust-lang/rust#48388 (bug fix + test)

Unresolved questions

  • None!

davidtwco avatar Feb 27 '24 17:02 davidtwco

r? @JohnTitor

rustbot has assigned @JohnTitor. They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

rustbot avatar Feb 27 '24 17:02 rustbot

The job mingw-check-tidy failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
Getting action download info
Download action repository 'msys2/[email protected]' (SHA:cc11e9188b693c2b100158c3322424c4cc1dadea)
Download action repository 'actions/checkout@v4' (SHA:b4ffde65f46336ab88eb53be808477a3936bae11)
Download action repository 'actions/upload-artifact@v3' (SHA:a8a3f3ad30e3422c9c7b888a15615d19a852ae32)
Complete job name: PR - mingw-check-tidy
git config --global core.autocrlf false
shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
---
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

COPY host-x86_64/mingw-check/reuse-requirements.txt /tmp/
RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-requirements.txt \
    && pip3 install virtualenv
COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/

# NOTE: intentionally uses python2 for x.py so we can test it still works.
# NOTE: intentionally uses python2 for x.py so we can test it still works.
# validate-toolstate only runs in our CI, so it's ok for it to only support python3.
ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test \
           --stage 0 src/tools/tidy tidyselftest --extra-checks=py:lint
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
#    pip-compile --allow-unsafe --generate-hashes reuse-requirements.in
---

#10 [5/8] COPY host-x86_64/mingw-check/reuse-requirements.txt /tmp/
#10 DONE 0.0s

#11 [6/8] RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-requirements.txt     && pip3 install virtualenv
#11 0.683   Downloading binaryornot-0.4.4-py2.py3-none-any.whl (9.0 kB)
#11 0.694 Collecting boolean-py==4.0
#11 0.697   Downloading boolean.py-4.0-py3-none-any.whl (25 kB)
#11 0.710 Collecting chardet==5.1.0
---
#11 3.699 Building wheels for collected packages: reuse
#11 3.700   Building wheel for reuse (pyproject.toml): started
#11 4.025   Building wheel for reuse (pyproject.toml): finished with status 'done'
#11 4.026   Created wheel for reuse: filename=reuse-1.1.0-cp310-cp310-manylinux_2_35_x86_64.whl size=181117 sha256=f5f58750481f69515c2c0d1d503daf565e2565c370d07fc6aeb95fe3498b4269
#11 4.026   Stored in directory: /tmp/pip-ephem-wheel-cache-m6zcu0zl/wheels/c2/3c/b9/1120c2ab4bd82694f7e6f0537dc5b9a085c13e2c69a8d0c76d
#11 4.029 Installing collected packages: boolean-py, binaryornot, setuptools, reuse, python-debian, markupsafe, license-expression, jinja2, chardet
#11 4.051   Attempting uninstall: setuptools
#11 4.052     Found existing installation: setuptools 59.6.0
#11 4.053     Not uninstalling setuptools at /usr/lib/python3/dist-packages, outside environment /usr
---
#11 5.260   Downloading virtualenv-20.25.1-py3-none-any.whl (3.8 MB)
#11 5.316      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.8/3.8 MB 69.8 MB/s eta 0:00:00
#11 5.364 Collecting filelock<4,>=3.12.2
#11 5.367   Downloading filelock-3.13.1-py3-none-any.whl (11 kB)
#11 5.382 Collecting distlib<1,>=0.3.7
#11 5.386   Downloading distlib-0.3.8-py2.py3-none-any.whl (468 kB)
#11 5.392      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 468.9/468.9 KB 118.2 MB/s eta 0:00:00
#11 5.419 Collecting platformdirs<5,>=3.9.1
#11 5.422   Downloading platformdirs-4.2.0-py3-none-any.whl (17 kB)
#11 5.532 Installing collected packages: distlib, platformdirs, filelock, virtualenv
#11 5.737 Successfully installed distlib-0.3.8 filelock-3.13.1 platformdirs-4.2.0 virtualenv-20.25.1
#11 DONE 5.8s

#12 [7/8] COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
#12 DONE 0.0s
---
DirectMap4k:      174016 kB
DirectMap2M:     7165952 kB
DirectMap1G:    11534336 kB
##[endgroup]
Executing TIDY_PRINT_DIFF=1 python2.7 ../x.py test            --stage 0 src/tools/tidy tidyselftest --extra-checks=py:lint
+ TIDY_PRINT_DIFF=1 python2.7 ../x.py test --stage 0 src/tools/tidy tidyselftest --extra-checks=py:lint
    Finished dev [unoptimized] target(s) in 0.03s
##[endgroup]
downloading https://ci-artifacts.rust-lang.org/rustc-builds-alt/b6e4299415646106095a7c3ca71aba9d174ee4ea/rust-dev-nightly-x86_64-unknown-linux-gnu.tar.xz
extracting /checkout/obj/build/cache/llvm-b6e4299415646106095a7c3ca71aba9d174ee4ea-true/rust-dev-nightly-x86_64-unknown-linux-gnu.tar.xz to /checkout/obj/build/x86_64-unknown-linux-gnu/ci-llvm
---
##[endgroup]
fmt check
tidy check
tidy: Skipping binary file check, read-only filesystem
##[error]tidy error: /checkout/src/doc/rustc/src/codegen-options/index.md:494: trailing whitespace
removing old virtual environment
creating virtual environment at '/checkout/obj/build/venv' using 'python3.10'
Requirement already satisfied: pip in ./build/venv/lib/python3.10/site-packages (24.0)
Collecting black==23.3.0 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 7))
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.7/1.7 MB 35.8 MB/s eta 0:00:00
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.7/1.7 MB 35.8 MB/s eta 0:00:00
Collecting click==8.1.3 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 34))
  Downloading click-8.1.3-py3-none-any.whl (96 kB)
Collecting importlib-metadata==6.7.0 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 38))
  Downloading importlib_metadata-6.7.0-py3-none-any.whl (22 kB)
  Downloading importlib_metadata-6.7.0-py3-none-any.whl (22 kB)
Collecting mypy-extensions==1.0.0 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 42))
  Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB)
Collecting packaging==23.1 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 46))
  Downloading packaging-23.1-py3-none-any.whl (48 kB)
Collecting pathspec==0.11.1 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 50))
  Downloading pathspec-0.11.1-py3-none-any.whl (29 kB)
  Downloading pathspec-0.11.1-py3-none-any.whl (29 kB)
Collecting platformdirs==3.6.0 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 54))
  Downloading platformdirs-3.6.0-py3-none-any.whl (16 kB)
Collecting ruff==0.0.272 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 58))
  Downloading ruff-0.0.272-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.9 MB)
Collecting tomli==2.0.1 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 77))
  Downloading tomli-2.0.1-py3-none-any.whl (12 kB)
Collecting typed-ast==1.5.4 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 81))
  Downloading typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (877 kB)
  Downloading typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (877 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 877.7/877.7 kB 135.4 MB/s eta 0:00:00
Collecting typing-extensions==4.6.3 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 107))
  Downloading typing_extensions-4.6.3-py3-none-any.whl (31 kB)
Collecting zipp==3.15.0 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 114))
  Downloading zipp-3.15.0-py3-none-any.whl (6.8 kB)
Installing collected packages: zipp, typing-extensions, typed-ast, tomli, ruff, platformdirs, pathspec, packaging, mypy-extensions, click, importlib-metadata, black
Successfully installed black-23.3.0 click-8.1.3 importlib-metadata-6.7.0 mypy-extensions-1.0.0 packaging-23.1 pathspec-0.11.1 platformdirs-3.6.0 ruff-0.0.272 tomli-2.0.1 typed-ast-1.5.4 typing-extensions-4.6.3 zipp-3.15.0
some tidy checks failed
Build completed unsuccessfully in 0:01:03
  local time: Tue Feb 27 17:12:45 UTC 2024
  network time: Tue, 27 Feb 2024 17:12:45 GMT

rust-log-analyzer avatar Feb 27 '24 17:02 rust-log-analyzer

Some questions:

  • Is this only relevant for the link step? i.e., would users wanting to disable it need -Zbuild-std?
  • Do we have any targets which support this but don't enable it at full by default at tier 2+?

Mark-Simulacrum avatar Feb 27 '24 17:02 Mark-Simulacrum

  • Is this only relevant for the link step? i.e., would users wanting to disable it need -Zbuild-std?

This does just pass flags to the linker. It would be useful with -Zbuild-std but also with no_std.

As far as I can tell, RELRO can be applied to shared objects as well as binaries, so you could have std with RELRO and the rest of your application without, or you could build a shared library to link with a C/C++ project and have that library use RELRO or not. I'm not completely certain about this, as the documentation about the linker flag is a little sparse, but I can observe that shared objects from libraries have RELRO in their program headers, so I assume it makes sense for libraries to have it.

  • Do we have any targets which support this but don't enable it at full by default at tier 2+?

From a cursory review of tier 2+ targets, it seems like we don't enable Full RELRO by default on Windows, Solaris/Illumos, Apple, Fuchsia, WebAssembly, and *-unknown-none targets. Some of these obviously don't support RELRO, like Windows or WebAssembly, as they don't use ELF. I'm not familiar enough with the others to say, and couldn't work it out with some brief research.

davidtwco avatar Feb 28 '24 11:02 davidtwco

I don't think I'm a good reviewer here, r? @Mark-Simulacrum

JohnTitor avatar Feb 28 '24 18:02 JohnTitor

Makes sense.

Some of these obviously don't support RELRO, like Windows or WebAssembly, as they don't use ELF

I'd imagine Windows has some equivalent, but I guess we don't have to expose it all under the same flag, especially if the defaults are mostly on the "secure" side of things rather than not.

@davidtwco do you want to kick off FCP? I don't think I can do that myself.

Mark-Simulacrum avatar Mar 09 '24 14:03 Mark-Simulacrum

@rfcbot fcp merge

davidtwco avatar Mar 11 '24 10:03 davidtwco

Team member @davidtwco has proposed to merge this. The next step is review by the rest of the tagged team members:

  • [x] @Aaron1011
  • [x] @cjgillot
  • [x] @compiler-errors
  • [x] @davidtwco
  • [x] @eddyb
  • [ ] @estebank
  • [x] @jackh726
  • [x] @lcnr
  • [x] @matthewjasper
  • [x] @michaelwoerister
  • [x] @nagisa
  • [x] @oli-obk
  • [x] @petrochenkov
  • [ ] @pnkfelix
  • [x] @wesleywiser

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

rfcbot avatar Mar 11 '24 10:03 rfcbot

:bell: This is now entering its final comment period, as per the review above. :bell:

rfcbot avatar Apr 04 '24 14:04 rfcbot

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

This will be merged soon.

rfcbot avatar Apr 14 '24 14:04 rfcbot

@Mark-Simulacrum this is ready to be reviewed and approved now that the FCP has finished

davidtwco avatar Apr 16 '24 12:04 davidtwco

@bors r+ rollup

Mark-Simulacrum avatar Apr 16 '24 12:04 Mark-Simulacrum

:pushpin: Commit 420c58fb119325325ec2f58f1686d7bcb63b51ad has been approved by Mark-Simulacrum

It is now in the queue for this repository.

bors avatar Apr 16 '24 12:04 bors