Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

A binary hardening system

License

NotificationsYou must be signed in to change notification settings

GJDuck/RedFat

Repository files navigation

RedFat is a tool for automatically hardening Linuxx86_64 ELF binaryexecutables against memory errors, includingbuffer overflows anduse-after-free errors.

RedFat is based on an amalgamation of two complementary memory errordetection technologies:

  • Poisoned Redzones
  • Low-Fat-Pointers

Using low-fat-pointers with binary code has some caveats, as is discussedbelow.

Releases

Binary releases of RedFat are available here:

Building

To build RedFat, simply run the script:

    $ ./build.sh

Basic Usage

To use RedFat. simply runredfat with the name of a binary executable,e.g.:

    $ ./redfat xterm

This will generate a hardenedxterm.redfat binary.To run the binary, thelibredfat.so runtime system must beLD_PRELOAD'edas follows:

    $ LD_PRELOAD=$PWD/libredfat.so ./xterm.redfat

Advanced Usage

The basic usage may suffer fromfalse detections with some binaries.This occurs when program (or compiler) deliberately creates out-of-bounds(OOB) pointers, and accessing such OOB pointers is indistinguishable from"real" memory errors under the basic low-fat-pointer checking.

To mitigate false detections, we can usedynamic analysis to determinewhich memory access operations are likely to cause false detections.

First, we build anallow-list-generation version of the binary:

    $ ./redfat -Xallowlist-gen xterm

This will generate anxterm.gen file that can be used to generate anallow-list.To use, run thegen version of the binary on a suitable test suite,ideally to maximize coverage:

    $ LD_PRELOAD=$PWD/libredfat.so ./xterm.gen

This process will generate anxterm.allow file which containsinformation about each memory access.

Next, we runredfat using the allow-list:

    $ ./redfat -Xallowlist-use xterm

This will generate a hardenedxterm.redfat binary.This version uses a more conservative instrumentation for memory accessoperations that are likely to be false detections.

Options

Theredfat tool supports several options to control the instrumentationand optimization levels.

The maininstrumentation options are:

  • -Xlowfat (-Xlowfat=false):Enables (disables) low fat pointer instrumentation.If disabled, the tool will use redzone-only checking.Default:enabled.

  • -Xreads (-Xreads=false):Enables (disables) memory read instrumentation.If disabled, the tool will only instrument memory writes.Note that (1) read instrumentation is expensive, and(2) many exploits (e.g.,control-flow-hijacking) require a memory writeoperation.For this reason, memory reads are not instrumented by default.Default:disabled.

  • -Xsize (-Xsize=false):Enables (disables) size metadata protection.RedFat stores object size metadata which itself may be vulnerable to attack.With size metadata protection, the size metadata is compared against the(immutable) low fat size metadata, which is sufficient to prevent overflowsinto adjacent objects.Default:enabled.

  • -Xdebug (-Xdebug=false):Enables "debugging" mode that prints detailed information about any memoryerror that is detected.SeeDebugging Mode below for more information.Default:disabled.

  • -Xadjust (-Xadjust=false):This experimental mode considers any pointer arithmetic from contextinstructions in the same basic-block.For example, if:

      add $0x8,%rdi  mov $0x0,(%rdi,%rsi,8)

    Then the base pointer for the low-fat check will be%rdi-0x8 rather thanjust%rdi (the default).This can improve the accuracy of low-fat checking.However, this mode also assumes the correctness of the basic-block recoveryalgorithm, so is not enabled by default.This mode is also not currently compatible with-Xdebug or-Xallowlist.

The mainoptimization options are:

  • -Oglobals (-Oglobals=false):Enables (disables) the elimination of global object memory accessinstrumentation that cannot reach the heap.Default:enabled.
  • -Ostack (-Ostack=false):Enables (disables) the elimination of stack object memory accessinstrumentation that cannot reach the heap.This optimization assumes that the stack pointer%rsp value is in thedefault relocation which is far from the heap.This is generally true for most programs, but the assumption could beviolated by programs that allocate and use custom stacks on the heap(e.g.,malloc()+sigaltstack()).Default:enabled.
  • -Obatch=N:Group the instrumentation into batches of lengthN checks, where possible.This instrumentation depends on a static jump target recovery analysis.If the analysis is imperfect, this may result in missed instrumentation.However, the analysis should be accurate for most binaries.Default: 50.
  • -Omerge (-Omerge=false):In a given batch, attempt to merge checks where possible.Default:enabled.
  • -OCFR (-OCFR=false):Enables (disables)Control Flow Recovery (CFR) mode.This makes the rewritten binaries faster, but may introduce rewritingerrors.Default:disabled.

The mainallow-list options are:

  • -Xallowlist-mode=MODE:Set the allow-list instrumentationmode for advanced instrumentationcontrol.Here, theMODE is represented by a 4-character string.The characterindex 0..3 determines how each allow-list entry(created byallow-list generation) should be instrumented.The possible index values are:

    • 0: Lowfat-unsafe (false detection observed)
    • 1: Lowfat-safe (no false detection observed)
    • 2: Only non-heap pointers observed
    • 3: Not reached

    The correspondingMODE[index] character determines the instrumentation:

    • L: Redzone+Lowfat instrumentation
    • R: Redzone-only instrumentation
    • -: No instrumentation

    Reasonable values forMODE are:

    • "RLRR": Use Redzone+Lowfat instrumentation only for(observed) lowfat-safe memory access.This is the defaultMODE.
    • "RL-R": Do not bother instrumenting memory access that was only(observed) using non-heap pointers.This can improve the performance of the instrumented binary,but at the risk of missing some memory errors on unexplored paths.
    • "RLLL": Use Redzone+Lowfat instrumentation on all memory accessthat was not (observed to be) Lowfat-unsafe.This eliminates the observed false detections, but retains the risk offalse detections on unexplored paths.

The LowFat runtime also supports options that can be enabled usingenvironment variables:

  • REDFAT_PROFILE=1: Enable profiling information such as the number ofallocations and total library checks.Default:disabled.
  • REDFAT_TEST=N: Enable "test"-mode that randomly (once perNallocations) underallocates by a single byte.If instrumented code accesses the missing byte then a memory error shouldbe detected.A zero value disables test-mode.Default: 0 (disabled).
  • REDFAT_QUARANTINE=N: Delay re-allocation of objects untilN bytes havebeen free'ed.This can help detect reuse-after-free errors by not immediatelyreallocating objects, at the cost of increased memory overheads.However, this can increase memory overheads.Note thatN is a per-region value for each allocation size-class, sothe total overhead could beN*M whereM is the number of regions(typically ~60).Default: 0.
  • REDFAT_ZERO=1: Enable the zero'ing of objects during deallocation.Provides additional defense againstuse-after-free errors and a basicdefense againstunititalized-read errors.However, zero'ing adds additional performance overheads.Default:disabled.
  • REDFAT_CANARY=1: Enables a randomized canary to be placed at the end ofall allocated objects.The canary provides additional protection against out-of-bound write errorsthat may go undetected in uninstrumented code.This consumes an additional 8 bytes per allocation.Note that a canary is always placed at the beginning of all allocatedobjects since this does not consume additional space.Default:disabled.
  • REDFAT_ASLR=1: EnablesAddress Space Layout Randomization (ASLR) forheap allocations.Default:enabled.
  • REDFAT_SIGNAL=SIG: If an error occurs, raise signalSIG to terminatethe program (or else fall back to abort).Default:SIGABRT.
  • REDFAT_LOG=N: SetN to be the log-level.Default: 2.

Debugging Mode

By default, RedFat can detect if a memory error occurs, but cannot report anyinformation about the memory error, such as the kind of error (overflow,use-after-free), the accessed object, etc.This is by design, since tracking this information would make theinstrumentation slower.

For more detailed information about memory errors, RedFat also supports a"debugging" mode that can be enabled via the-Xdebug option:

   $ ./redfat -Xdebug xterm

Unlike the default mode, the debugging mode will print detailed informationabout any memory error detected.For example:

    REDFAT WARNING: out-of-bounds error detected!            instruction = movb $0x0, -0x20(%rdx) [0x2d698]            access.ptr  = 0x3073820560            access.size = 1            access.obj  = [-48..+16]            base.ptr    = 0x3073820580 (+32)            base.obj    = [+48..+144] (free)

Here:

  • instruction: is the instruction and [address] where the memory errorwas detected.
  • access.ptr: is the pointer that was accessed by the instruction.
  • access.size: is the size of the access in bytes.
  • access.obj: is the (free?) object that was accessed(relative toaccess.ptr).
  • base.ptr: is the base pointer with (offset) relative toaccess.ptr.
  • base.obj: is the (free?) object pointed to by the base pointer(relative toaccess.ptr).

In this example, the base and access pointers refer to different objects,meaning that the access is deemed to be a out-of-bounds memory error.

Unlike the default mode:

  • The program willnot be terminated if a memory error is detected.However, at most one message will be printed for each instruction.
  • There is no allow-list, so false positives will be reported just the sameas real memory errors.
  • Debugging mode is significantly slower than the default mode.

Profiling Mode

RedFat supports a "profiling" mode that can be enabled via the-P option:

   $ ./redfat -P xterm

Profiling mode is similar to the default mode,but the following information to the terminal on program exit:

  • total.time: Total runtime (ms).
  • total.maxrss: Maxresident set size (kB).
  • redzone.checks: Total redzone checks (before-Omerge).
  • redzone.checks (optimized): Total redzone checks (after-Omerge).
  • redzone.checks (heap): Total redzone checks (after-Omerge) onheap pointers.
  • lowfat.checks: Total lowfat checks (before-Omerge).
  • lowfat.checks (optimized): Total lowfat checks (after-Omerge).
  • lowfat.checks (heap): Total lowfat checks (after-Omerge) onheap pointers.

By enabling theREDFAT_PROFILE=1 environment variable, additionalinformation will be printed:

  • total.allocs: Total heap allocations.
  • library.checks: Total library function (e.g.,memset,memcpy, etc.)checks.
  • library.checks (heap): Total library function checks on heap pointers.

Note that:

  • RedFat can only detect memory errors on heap pointers(heap).
  • Profiling mode is somewhat slower than the default mode.
  • Profiling information willnot be printed if the instrumented binaryexits abnormally (e.g., crash) or if the binary calls fast exit(e.g.,_Exit(), etc.).

The ratio of heap versus non-heap pointers depends on the program, and how itchooses to allocate and access memory.If the ratio of(heap) is low, it may not be worthwhile to use RedFat onthe binary.

Limitations

  • RedFat inherits all the limitations of the underlying E9Tool/E9Patchtool chain.Fortunately, E9Patch should work for most binaries.
  • RedFat can detectobject-bounds (e.g., buffer overflow) and(re)use-after-free errors, but notsub-object-bounds nortype-confusion errors.The latter are difficult to detect at the binary-level which lacks typeinformation.
  • RedFat is based onstatic binary rewriting, which means that only thebinary explicitly passed to RedFat will be instrumented, andnot anydynamically linked library dependencies.It is possible to separately instrument library dependencies withRedFat, and useLD_LIBRARY_PATH to replace the default (uninstrumented)library.
  • Low-fat-pointer checking is limited to unambigious pointer arithmetic.In practice, this meansx86_64 memory operands only.

Troubleshooting

Generally, most binaries should work without an issue.When a problem does occur, it is usually one of the following:

  • error: binary "program" exports a custom "malloc" function:This occurs when an executable defines its ownmalloc() function andexports it.If this occurs, theLD_PRELOAD trick will not replace this custom malloc,meaning that the instrumented binary will not be protected.You can force instrumentation anyway (e.g., for performance testing) usingthe-force option:

      $ ./redfat -force xterm

    For some binaries, it may be possible to manually remove the custommalloc (with some effort) using a separate binary rewriting (e.g., overwriteentries in the dynamic symbol table).However, this functionality is not currently provided by RedFat itself.

  • warning: failed to disassemble byte 0xXX at address 0xYYYY in section ".text":This warning occurs when data is detected in the code section(s).This can be fixed by manually excluding specific address ranges fromdisassembly using the E9Tool-E option, e.g.:

       $ ./redfat xterm -- -E ADDR1..ADDR2

    Here,ADDR1..ADDR2 is the address range to exclude from disassembly.

    Note that E9Tool (and by extension, RedFat) only uses a basic (linear)disassembler by default.This works for most binaries, but not binaries that mix code and data.For the latter, some kind of manual disassembly (using-E) isrecommended.

  • warning: the number of virtual mappings (XXX) exceeds the default system limit (YYY):This occurs when the instrumented binary uses too many mappings.This can be fixed by increasing the mapping size to a suitable new limit(ZZZ > XXX):

       $ sudo sysctl -w vm.max_map_count=ZZZ

    Alternatively, the issue can be fixed by decreasing the compression level(at the cost of larger instrumented binary file sizes) using the E9Tool-c option, e.g.:

       $ ./redfat xterm -- -c N

    whereN is a number0..9 (lower numbers mean less compression).

  • e9patch loader error: mmap(addr=ADDR,size=SIZE,offset=+OFFSET,prot=PROT) failed (errno=12):This error occurs when you attempt to run an instrumented binary that usestoo many mappings.See above for the problem description and solution.

  • REDFAT ERROR: the REDFAT runtime (libredfat.so) has not been LD_PRELOAD'ed:As the error message explains, this error occurs when you attempt to run aninstrumented binary withoutLD_PRELOAD'ing thelibredfat.so binary.You can also defineREDFAT_DISABLE=1 to run the binary anyway (butwith the instrumentation costs and no memory error protection).

  • REDFAT ERROR: out-of-bounds/use-after-free error detected!:A memory error was detected.If the binary wasnot instrumented with-Xallowlist-use, then thiscould be afalse detection (see theAdvanced Usage above).Otherwise, this could be a genuine error and should be investigated.

  • Illegal Instruction:This could be a memory error detected by RedFat.By default, RedFat will raise theSIGILL (Illegal Instruction) signalwhenever a out-of-bounds/use-after-free error is detected.The signal is raised using thex86_64ud2 instruction.Normally, the RedFat runtime system will catch the signal and print theerror detected message shown above.However, if the program resets the signal handler, or installs adifferent signal handler, the error may be reported as an illegalinstruction.

  • Segmentation Fault:"Wildly" out-of-bounds errors may result in aSIGSEGV rather than aSIGILL.Alternatively, this could be some other issue, such as the binary breakingone of the assumptions of static rewriting (e.g., self-modifying code),or some other bug (please report it).

License

This software has been released under the GNU Public License (GPL) Version 3.

Some specific files are released under the MIT license (check the filepreamble).

Authors

RedFat is written by Gregory J. Duck.The initial prototyping and testing of RedFat was completed by Yuntong Zhang.

Publication

See Also

  • LibRedFat: A hardened malloc implementation.
  • E9Patch: A scalable binary rewriting system.
  • LowFat: Lean C/C++ bounds checking with low-fat pointers

Bugs

RedFat is considered beta-quality software.Please report bugs here:

Acknowledgements

This work was partially supported by the National Satellite of Excellence inTrustworthy Software Systems, funded by the National Research Foundation (NRF)Singapore under the National Cybersecurity R&D (NCR) programme.

This work was partially supported by the Ministry of Education, Singapore(Grant No. MOE2018-T2-1-142).


[8]ページ先頭

©2009-2025 Movatter.jp