PUMM: Preventing Use-After-Free Using Execution Unit Partitioning

Slide Note
Embed
Share

Memory-unsafe languages like C and C++ are prone to Use-After-Free (UAF) vulnerabilities. PUMM introduces execution unit partitioning to efficiently tackle this issue. By segregating and managing execution units, PUMM aims to prevent UAF exploits and enhance software security.


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. Download presentation by click this link. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.



Uploaded on Apr 02, 2024 | 0 Views


Presentation Transcript


  1. PUMM: Preventing Use-After-Free Using Execution Unit Partitioning Carter Yagemann, The Ohio State University Simon P. Chung, Brendan Saltaformaggio, and Wenke Lee, Georgia Institute of Technology 32nd USENIX Security Symposium (Summer, 2023)

  2. Outline 01 05 Introduction Limitations 02 06 Overview Related Work Design Conclusion 03 07 04 Evaluation 1

  3. Introduction 2

  4. Introduction Memory-unsafe languages like C and C++ are common in software development. These languages often contain binary-level vulnerabilities that attackers exploit. One prevalent and challenging-to-detect vulnerability is Use-After-Free (UAF). UAF occurs when a program frees memory but later still tries to use it through a dangling pointer. UAF can lead to program crashes, arbitrary code execution. In 2020, NIST published numerous UAF advisories for popular software like Chrome and Firefox. 3

  5. Introduction In recent years, two strategies have emerged to solve this problem: scanning and one-time allocation (OTA). In the scanning approach, freed addresses are quarantined until a scan of memory verifies that no possible pointers remain, at which point they are released for reallocation. Conceptually, scanning is similar to retrofitting garbage collection into program binaries. The OTA approach enforces that an allocated address will never be reallocated again during the program s lifetime. 4

  6. Overview 5

  7. Overview 6

  8. Design 7

  9. Design System architecture 8

  10. Design process trace 9

  11. Design Control Flow Graph 7 1 1. for i in range(10): 2. # Code block A 3. if (i % 2 == 0): 4. # Code block B 5. else: 6. # Code block C 7. 8. for j in range(5): 9. # Code block D 2 8 3 4 9 6 5 10

  12. Design Execution Unit Partitioning PUMM's core idea lies in efficiently identifying execution units within programs, such as those handling network requests or input files. These units often operate within a main task loop, initiating a new task iteration until an exit condition is met. PUMM's challenge is distinguishing these units from nested loops that can prematurely release quarantined memory. 7 1 2 8 unit 3 4 9 6 5 11

  13. Design Policy Generation & Enforcement Our solution stems from the observation that most execution units begin with initializing variables, including ones that are dynamically allocated. Code blocks calling the underlying memory management library to allocate new variables can be identified by the last return address pushed onto the stack without requiring stack unwinding Since these calls occur at the beginning of new unit iterations, quarantined memory from prior iterations can be released with low risk. 12

  14. Evaluation 13

  15. Evaluation - Environment Operating System: Debian Buster CPU: Intel Core i7-6700K Memory: 16 GB RAM Storage: SSD The study compared PUMM against two baseline defense systems: MarkUs for scanning-based defense and FFmalloc for OTA (One Time Allocation) defense. 14

  16. Evaluation 15

  17. Evaluation 16

  18. Evaluation 17

  19. Runtime overhead Runtime overhead on the real-world program dataset. PUMM, MarkUs, and FFmalloc s average overheads are 2.04%, 13.02%, and 4.78%, respectively. 18

  20. Memory overhead Memory overhead on the real-world program dataset. PUMM, MarkUs, and FFmalloc s average overheads are 16.48%, 68.45%, and 823.90%, respectively. 20 19

  21. Spec 2006 benchmark Performance Evaluation: SPEC CPU2006 is a widely used performance benchmark Diverse Workloads: SPEC CPU2006 encompasses multiple distinct test programs that simulate various types of computational workloads. These workloads include both integer and floating-point computations. Comparability: Using SPEC CPU2006 as a benchmark test provides the advantage of comparability. It is widely recognized and accepted in the research community, making it easier for researchers to compare the performance of different methods. 20

  22. Runtime overhead Runtime overhead for the SPEC CPU2006 benchmark. PUMM, MarkUs, and FFmalloc s average overheads are 3.12%, 37.41%, and 17.09% with geometric means of 0.57%, 9.62%, and 2.27%, respectively. 22 21

  23. Memory overhead Memory overhead for the SPEC CPU2006 benchmark. PUMM, MarkUs, and FFmalloc s average overheads are 1.87%, 159.17%, and 288.19% with geometric means of 0.09%, 17.76%, and 125.57%, respectively. 23 22

  24. Limitations 23

  25. Limitations Code Coverage: Dynamic profiling-based systems, including PUMM, may not achieve complete code coverage during profiling. PUMM identifies execution unit heads, often the outermost program loops, making it robust. Techniques like fuzzing and symbolic analysis can expand code coverage. Dynamically Generated Code: PUMM can't release the quarantine list for dynamically generated code. For programs with untrusted dynamic code, PUMM treats all dynamic code as part of the same unit. Entirely dynamically generated code leads to an OTA policy. 24

  26. Limitations Security Guarantee: EUP, while trusted, relies on heuristics that can be violated by developers. PUMM, while providing lower overhead than scanning and OTA defenses, doesn't guarantee security to the same degree as MarkUs and FFmalloc. PUMM halts all 40 real-world vulnerabilities and effectively protects against synthetic UAFs. Compiler Optimized Code: Stack return pointers for caller identification can't detect optimized tail call elimination by the compiler. Tail call elimination doesn't impact PUMM's performance, as demonstrated in the evaluation. 25

  27. Related work 26

  28. Related work Secure allocators like DieHard, DieHarder, FreeGuard, and Guarder have aimed to prevent memory safety violations by controlling object placement and memory reuse. Pointer invalidation techniques focus on nullifying dangling pointers or labels but often require source code and can have high overhead. Use-After-Free (UAF) detection tools like Valgrind and AddressSanitizer exist but are mainly for debugging and have high overhead, making them less practical for security. Fuzz testing can find UAF bugs, but achieving complete code coverage is challenging. 27

  29. Conclusion 28

  30. Conclusion This paper propose a new design for preventing UAF exploitation based on deferred reallocation and EUP. Using dynamic profiling and analysis, our design identifies autonomous execution units in programs without source code, deferring freed memory from reallocation until after the current unit instance has ended. Our Linux prototype, PUMM, successfully prevents 40 UAF vulnerabilities from being exploited in 26 real- world programs while incurring 2.74% less execution overhead and 52.0% less memory overhead than scanning and OTA-based defenses. Against 3,000 synthetically generated UAFs, only 4 remain exploitable under PUMM s protection. 29

  31. THANKS! 30

Related


More Related Content