Skip to content
This repository has been archived by the owner on Mar 2, 2023. It is now read-only.

Security implications of guided linking #4

Open
eternaleye opened this issue Mar 14, 2021 · 3 comments
Open

Security implications of guided linking #4

eternaleye opened this issue Mar 14, 2021 · 3 comments

Comments

@eternaleye
Copy link

One concern I have, in looking at guided linking, is that it potentially causes a huge increase in the ROP surface of all programs linked using it. If it were possible to specify portions of the optimized set which, in the optimized output, must not have any (transitive) dependency between them, this could significantly alleviate the issue.

To illustrate, let's start with the simple optimized set given in Fig. 1 of the paper: program1 IR needs library IR; program2 IR needs library IR. If we consider the case where program1 is some normal program expected to be run by unprivileged users, and program2 is a tiny helper program that is SetUID in order to obtain specific resources it then hands off to program1, but both use the same set of libraries, then guided linking may significantly reduce the overall security of the system.

If, however, it was possible to state that no dependency relationship may be created from code in program2 IR to code in program1 IR (with being in the same merged library counting as a dependency relationship in both directions), this problem could be avoided.

@yotann
Copy link
Owner

yotann commented Apr 5, 2021

It's true that guided linking could greatly increase the number of ROP gadgets. (It can also eliminate gadgets by removing dead library code, but in many cases the gadget-increasing effect will predominate.)

One important thing to keep in mind is that the number of gadgets isn't an especially good measure of security. Attackers only need a few dozen gadgets of the right types to gain control; if the original programs already have a sufficient set of gadgets, guided linking won't make their security any worse. This is almost certainly true for large programs such as Clang, but of course not all programs are that large.

It sounds like you're suggesting a new constraint that would effectively say "program2 must not have any extra code included in its address space" (or more specifically, it may not have any of program1's code added to its address space.) My concern is that this would offer limited security (as program1 could still get lots of new gadgets), while also significantly limiting the amount of optimization guided linking can do.

I've talked with @jtcriswell about this, and he was interested in extending control-flow integrity to work on code produced by guided linking. An extended version of CFI could guarantee that code from one program can only ever reach code that belongs to that program or its original libraries, preventing the use of any new gadgets from other merged code. The tricky part would be handling library calls that make (indirect) calls to functions in multiple different merged programs.

In any case, I certainly wouldn't use an experimental technique like this on a SetUID program!

@yotann yotann changed the title Support "isolation"/"antidependency" constraints during guided linking? Security implications of guided linking Apr 5, 2021
@eternaleye
Copy link
Author

That all makes sense to me, yeah - part of my thinking was that SetUID programs end up (transitively) depending on a surprising amount of the system, and so a lot of "...only used by code within the optimized set" constraints end up with limited utility - doubly so if you also consider non-SetUID but still privileged services.

As far as "library calls that make (indirect) calls to functions in multiple different merged programs", I presume libpng and its png_set_error_fn (or rather, every libpng function that may error, when that has been used to set a handler) is an example of this?

@yotann
Copy link
Owner

yotann commented Apr 8, 2021

Yes, C functions that use callbacks like qsort and png_set_error_fn would qualify. The more common case would be C++ virtual functions in libraries that get overridden by functions in the program.

I'm pretty confident extending CFI would work. Someone would just need to work out exactly how to do it.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants