Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Memory exploit mitigation #145

Closed
wants to merge 1 commit into from

Conversation

kmcallister
Copy link
Contributor

@kmcallister kmcallister commented Jun 27, 2014

@zwarich
Copy link
Contributor

zwarich commented Jun 29, 2014

I'm not sure I like the magic integer levels of protection.

@kmcallister
Copy link
Contributor Author

kmcallister commented Jun 30, 2014

What about it specifically?

@zwarich
Copy link
Contributor

zwarich commented Jun 30, 2014

I would prefer descriptive names rather than integers.

@pczarn
Copy link

pczarn commented Jun 30, 2014

Integer levels symbolize the acceptable cost that varies between platforms for certain measures. I would prefer approximate cost passed as a percentage of slowdown.

  • --harden-cost 5 rather than --harden-level 1
  • --harden-cost 20 for --harden-level 2
  • --harden-cost 90 for --harden-level 3

@kmcallister
Copy link
Contributor Author

kmcallister commented Jun 30, 2014

@zwarich: Okay, something like none, mild, full, extreme? Integer levels are already established practice for optimization, but maybe we should improve the status quo and use descriptive names for optimization as well.

@pczarn: I think users will get annoyed at how rough these approximations are. The actual cost depends a lot on the program you're compiling.


The intent is that most users will not use this attribute, and will instead pass the compiler flag `--harden-level <N>`, or `-H` as shorthand for `--harden-level 1`. The meaning of the levels is:

* `--harden-level 0` — No hardening. We may still incidentally do things that make exploits harder, if they have no undesirable impact.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None should be none. If I want to disable any changes to the source from these changes I should be able to.

Copy link
Contributor Author

@kmcallister kmcallister Jul 1, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really think of it as "changes to the source", since the translation from Rust source to machine code is always very complex. I was more thinking, if there are natural things to do in codegen that would incidentally make exploits harder, we don't need to go out of our way to disable those things at -H0. But I'm not sure what would go in that category, and I do see the appeal of a setting for "make compilation as simple as possible", even if it's still not very simple :)

@bharrisau
Copy link

bharrisau commented Jul 1, 2014

The proposed 0-3 looks similar enough to the well known GCC optimisation levels. None, quick+dont_increase_size, slow+dont_increase_size, maximum.

The biggest difference is between the -O2 and -H2 modes, -H2 is closer to -O3 than -O2. Given -O2 is the 'common' optimisation level perhaps it would be better to have something like the following (sorry for the bikeshedding).

  • 0 - No hardening.
  • 1 - Incidental things that make exploits harder, if they have no undesirable impact.
  • 2 - A level of hardening suitable for most software.
  • 3 - A level of hardening suitable for production software which heavily prioritizes security.
  • 4 - Maximum hardening.

I know this adds another level, but it matches much closer to the -O system. I'm not sure -H4 has much use except for experimenting/testing.

@pczarn
Copy link

pczarn commented Jul 1, 2014

You convinced me that levels of hardening are most suitable.

Remember that -O4 doesn't exist, it's an alias for -O3. LTO is enabled separately. Let's look for similarities between optimization and protection. Is RELRO sort of a link time hardening?

@thestinger
Copy link

thestinger commented Jul 2, 2014

RELRO makes the GOT read-only after the linker sets up the function pointers, so full RELRO requires using immediate binding. You can use both PIE (for a randomized base) and full RELRO today with -C link-args="-Wl,-pie,-z,relro,-z,now".

@thestinger
Copy link

thestinger commented Aug 8, 2014

AFAIK PIE is the only reason for using LLVM's pic relocation model for an executable, so it can simply be enabled if the relocation model is pic. That's already the default model, so it will be enabled by default everywhere. It may make sense to use dynamic-no-pic by default on architectures like i686 where position independent code is expensive, but that's a separate issue and -C relocation-model=dynamic-no-pic is already possible. See rust-lang/rust#16340.

@brson
Copy link
Contributor

brson commented Aug 26, 2014

Discussed in https://github.com/rust-lang/meeting-minutes/blob/master/weekly-meetings/2014-08-26.md

@kmcallister the feeling right now is that we're kind of uneasy about 'hardening' as an independent concept in Rust, and would basically like to let the requirements bake more. In the meantime, the individual codegen features involved would be considered on their own merits as codegen compiler flags, and don't need RFC's. In other words, let's go ahead and get started on adding the required codegen functionality to the compiler, but not commit to any unifying framework.

In the future, we should revisit, and possibly take a more holistic look at how codegen options are managed generally (not just those that relate to hardening).

Closing.

@brson brson closed this Aug 26, 2014
wycats pushed a commit to wycats/rust-rfcs that referenced this pull request Mar 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants