Skip to content

Commit

Permalink
Consolidate RELRO
Browse files Browse the repository at this point in the history
  • Loading branch information
robertdfrench committed Jul 23, 2024
1 parent 4e81a11 commit d78722b
Showing 1 changed file with 20 additions and 34 deletions.
54 changes: 20 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,28 +254,6 @@ This indirection is part of what allows programs to work without
necessarily knowing where all of their symbols are ahead of time.


#### Partial RELRO
![](memes/boromir_got.png)

Updating the GOT at runtime means that the memory page containing the
GOT must always be writable. This isn't ideal from a security
perspective. An attacker who can inject a malicious payload into the
program may be able to overwrite values in the GOT, giving them some
control over how the program behaves. To prevent this, GCC introduced an
option called [Relocation Read-only][sidhpurwala] or "RELRO".

RELRO comes in two flavors: Full and Partial. Partial RELRO tells the
dynamic linker to do the following:

* Resolve GOT entries for all `extern` variables
* Mark these entries read-only by calling [`mprotect(2)`][mprotect]
* Call the program's `main` function

Partial RELRO helps protect the integrity of the GOT by marking is
read-only as soon as all legitimate modifications are done. We'll talk
about [Full RELRO](#full-relro) in the next section.



### Procedure Linkage Table
The Procedure Linking Table (PLT) uses the GOT to help programs to
Expand Down Expand Up @@ -379,19 +357,26 @@ compiler will create a "stub" function in the Procedure
Linkage Table (PLT).


#### Full RELRO
Part of the original purpose of the PLT was to enable *lazy-binding*:
delaying the lookup of dynamic symbols until the first time they're
needed. However, this means that the GOT needs to remain writable until
all symbols have been resolved. If a program does not take all code
paths that use dynamic symbols, its GOT will remain writable the entire
time it is running.

Full RELRO tells the dynamic linker to resolve all symbols before a
program begins executing, and then mark the GOT read-only by calling
[`mprotect(2)`][mprotect]. This prevents the GOT from being modified by
an attacker, but it also makes program startup slower because every
dynamic symbol must be resolved before the `main` function can begin.
### RELRO
![](memes/boromir_got.png)

Updating the GOT at runtime means that the memory page containing the
GOT must always be writable. This isn't ideal from a security
perspective. An attacker who can inject a malicious payload into the
program may be able to overwrite values in the GOT, giving them some
control over how the program behaves. To prevent this, GCC introduced an
option called [Relocation Read-only][sidhpurwala] or "RELRO".

RELRO comes in two flavors: Full and Partial. Partial RELRO tells the
dynamic linker to do the following:

* Resolve GOT entries for all `extern` variables
* Mark these entries read-only by calling [`mprotect(2)`][mprotect]
* Call the program's `main` function

Full RELRO tells the dynamic linker to resolve *all* symbols before a
program begins executing, even functions.

You can check what (if any) degree of RELRO is enabled by running
[checksec(1)][checksec]. For example, we can inspect the
Expand All @@ -406,6 +391,7 @@ Partial RELRO No canary found NX enabled No PIE No RPATH No RU




## What is GNU IFUNC *supposed* do?
It allows you to determine, at runtime, which version of some function
you'd like to use. It does this by giving you to an opportunity to run
Expand Down

0 comments on commit d78722b

Please sign in to comment.