Introduction

GCC & plugins

Instrumentation 1

PaX - gcc plugins galore
PaX Team
H2HC 2013.10.05

PaX - gcc plugins galore

Instrumentation 2

Introduction

GCC & plugins

Introduction
PaX/grsecurity
GCC & plugins
Instrumentation 1
Instrumentation 2

PaX - gcc plugins galore

Instrumentation 1

Instrumentation 2

Introduction

GCC & plugins

Instrumentation 1

PaX/grsecurity

Overview

I Host Intrusion Prevention System
I Focus: exploitation of memory corruption bugs
I Threat model: arbitrary read-write memory access
I Bugs vs. Exploits vs. Exploit techniques
I Performance vs. Usability
I 2000-2013, linux 2.2-3.11

PaX - gcc plugins galore

Instrumentation 2

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

PaX/grsecurity

Exploit Techniques & Defenses
I Execute new (injected) code (shellcode) → non-executablepages, runtime code generation control, ASLRI Execute existing code out-of-(intended)-order (return-to-libc,

ROP/JOP) → control flow integrity, ASLRI Execute existing code in-(intended)-order (data-only attacks)→ open question

I Increasing order of difficulty
I Decreasing amount of control

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

PaX/grsecurity

Memory Corruption Bugs
I “Precursor” bugs included (memory disclosure, unintended

reads, etc)

I Two generic goals:
I Find them in the source
I Catch them before they trigger
I Too many kinds to cover them with universal approaches
I see http://cwe.mitre.org/

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

PaX/grsecurity

Why GCC Plugins?
I De facto compiler in the linux world
I Compiler is the bridge between source code and machine code
I Read(analysis)/Write(instrumentation) access to the internal

representation of the program

I Access to all kinds of meta information for free (CFG, data

flow, etc)

I Idea: add special instrumentation during compilation to

detect/prevent entire bug classes at runtime

I You’ll learn C for real :)PaX - gcc plugins galoreIntroduction

GCC & plugins

Introduction
GCC & plugins
GCC Overview
GCC Plugins
Instrumentation 1
Instrumentation 2

PaX - gcc plugins galore

Instrumentation 1

Instrumentation 2

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

GCC Overview

I GCC = GNU C Compiler, GNU Compiler Collection, FSF’s

flagship project

I Languages: C, C++, Objective-C, Objective-C++, Go, Ada,

Java, Fortran, GIMPLE

I GCC itself is written in C (and since 4.7 more and more C++)I C dialects: C90 (c90, gnu90), C99 (c99, gnu99), C11 (c11,gnu11)I License: GPLv3 since 4.2.2 (2007.10.7)
I Plugin support since 4.5 (2010.04.14), GPLv3 with runtime

library exception

I GCC Resource Center at IITB (Indian Institute of Technology,

Bombay)PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

GCC Overview

I Compilation process is a pipeline, driven by the compiler driver
I C: preprocessor, compiler, assembler, linker
I Compiler: single process that
I parses the source code into an Abstract Syntax TreeI verifies the AST
I transforms the AST into an intermediate representation (IR)I optimizes the IR
I transforms the IR into assembly

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

GCC Overview

I GCC AST: language frontends produce GENERIC
I Data structure: tree
I Plugins can implement new attributes and pragmas, inspect

structure declarations and variable definitions (gcc 4.6+)

I GCC IR #1: GIMPLE
I Static Single Assignment (SSA) based representation
I First set of optimization/transformation passes runs on

GIMPLE (-fdump-ipa-all, -fdump-tree-all)

I Data structures: cgraph_node, function, basic_block,

gimple, tree
I GCC IR #2: RTL
I GIMPLE is lowered to RTL (pre-SSA gcc had only this)
I Second set of optimization passes runs on RTL(-fdump-rtl-all)

I Data structures: rtx, tree
PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

GCC Overview

I machmode.def, tree.def, gimple.def, rtl.def
I machine modes: VOIDmode, SImode, DImode, TImodeI tree codes (~200 in 4.8): ERROR_MARK, IDENTIFIER_NODE,INTEGER_TYPE, POINTER_TYPE, ARRAY_TYPE, RECORD_TYPE,
VOID_TYPE, FUNCTION_TYPE, FUNCTION_DECL, FIELD_DECL,VAR_DECL, PARM_DECL, TYPE_DECL, COMPONENT_REF,
ARRAY_REF, INDIRECT_REF, INTEGER_CST, STRING_CST, etc
I gimple codes (~40 in 4.8): GIMPLE_ASSIGN, GIMPLE_ASM,

GIMPLE_CALL, GIMPLE_PHI, GIMPLE_NOP, GIMPLE_COND,GIMPLE_SWITCH, GIMPLE_RETURN, etc
I rtl codes (~200 in 4.8): MEM, REG, RETURN, CLOBBER, SET,BARRIER, INSN, etc

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

GCC Overview# include < stdio .h >int main ( int argc , char * argv []){return puts ( " hello world !\ n " );}I gcc-4.8.1-O2 -fdump-tree-all -fdump-ipa-all-fdump-rtl-all -fdump-passes

I 97 SSA dumps
I 9 IPA dumps
I 57 RTL dumps

PaX - gcc plugins galore

Instrumentation 2

Introduction

GCC & plugins

Instrumentation 1

Instrumentation 2

GCC Overview-fdump-tree-ssa-raw
Listing 1: hello.c.016t.ssa;; Function main ( main , funcdef_no =24 , decl_uid =2380 , cgraph_uid =2
main ( int argc , char * * argv ){int _3 ;< bb 2 >:gimple_call < puts , _3 , " hello world !\ n " >gimple_return <_3 >}PaX - gcc plugins galoreIntroduction

GCC & plugins

Instrumentation 1

Instrumentation 2

GCC Overview-fdump-tree-ssa
Listing 2: hello.c.016t.ssa;; Function main ( main , funcdef_no =24 , decl_uid =2380 , cgraph_uid =2
main ( int argc , char * * argv ){int _3 ;< bb 2 >:_3 = puts ( " hello world !\ n " );return _3 ;}PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

GCC Plugins

I Loadable module system introduced in gcc 4.5
I Shared library loaded early right after command line parsing
I No well defined API, all public symbols available for plugin use
I Typical (intended :) use: new IPA/GIMPLE/RTL passes
I Plugins can sign up for events, insert/remove/replace passes
I No (easy) access to language frontends

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

GCC Plugins

Comparison
I Related technologies: checkpatch.pl/coccinelle/sparse
I AST vs. GIMPLE/RTL
I Extra run vs. part of the regular compilation
I checkpatch.pl: no modification, source code analysis(pre-AST)

I sparse: no modification, only analysis
I coccinelle: modification by generating source patches →doesn’t scale, harder to maintain

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

GCC Plugins

Structure
I Some boilerplate code: plugin_is_GPL_compatible,

plugin_info, plugin_init
I Pass registration: register_callback,register_pass_info, simple_ipa_opt_pass,
ipa_opt_pass_d, gimple_opt_pass, rtl_opt_pass
I Callbacks: PLUGIN_INFO, PLUGIN_START_UNIT,PLUGIN_PASS_MANAGER_SETUP, PLUGIN_ATTRIBUTES,PLUGIN_FINISH_TYPE, PLUGIN_FINISH_DECL
I opt_pass: type, name, gate, execute, pass number,properties, todo flags

PaX - gcc plugins galore

Instrumentation 2

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

GCC Plugins

Building
I C (4.5, 4.6, 4.7) vs. C++ (4.7, 4.8+)
I Limited support for designated initializers in C++
I Cross-compilation: with the native compiler!
I BUILDING_GCC_VERSION, GCCPLUGIN_VERSION (since 4.7)
I No easy way to detect/depend on the target arch
I __ARCH__ gives the wrong result for cross-compilation!
I Better plan: gcc-plugin-compat.h

PaX - gcc plugins galoreIntroduction

GCC & plugins

Instrumentation 1

Instrumentation 2

Introduction
GCC & plugins
Instrumentation 1
Structure Constification (CONSTIFY)
Latent Entropy Extraction (LATENT_ENTROPY)
Kernel Stack Leak Reduction (STACKLEAK/STRUCTLEAK)
Instrumentation 2

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

Structure Constification (CONSTIFY)

Overview
I Automatic constification of ops structures (200+ types inlinux)I Structures with function pointer members only
I Structures explicitly marked with a do_const attribute
I no_const attribute for special cases
I Unfortunately many ops structures want to be written atruntime

I Local variables not allowed (compiler error generated)

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

Structure Constification (CONSTIFY)CONSTIFYI PLUGIN_ATTRIBUTES callback: registers do_const andno_const attributes

I Linux code patched by hand
I Could be automated (static analysis, LTO)I PLUGIN_FINISH_TYPE callback: sets TYPE_READONLY and

C_TYPE_FIELDS_READONLY on eligible structure types
I Only function pointer members, recursively
I do_const is set, no_const is not set

I End result is that the frontend will do the dirty job ofenforcing C variable constness
I GIMPLE pass: constified types cannot be used for local
variables (stack is writable :)PaX - gcc plugins galoreIntroduction

GCC & plugins

Instrumentation 1

Instrumentation 2

Structure Constification (CONSTIFY)

1
2
3
4
5
6
7
8
9
10
11
12
13
14

static bool constifiable ( tree node ) {tree field = TYPE_FIELDS ( node );for (; field ; field = TREE_CHAIN ( field )) {fieldtype = TREE_TYPE ( field );if ( TREE_CODE ( fieldtype ) == POINTER_TYPE &&TREE_CODE ( TREE_TYPE ( fieldtype )) == FUNCTION_TYPE )co n t i n u e ;if ( TREE_CODE ( fieldtype ) == RECORD_TYPE &&constifiable ( fieldtype ))continue ;return false ;}return true ;}PaX - gcc plugins galoreIntroduction

GCC & plugins

Instrumentation 1

Structure Constification (CONSTIFY)

static void constify_type ( tree type ){TYPE_READONLY ( type ) = 1;
C _ T Y P E _ F I E L D S _ R E A D O N L Y ( type ) = 1;
T Y P E _ C O N S T I F Y _ V I S I T E D ( type ) = 1;}

PaX - gcc plugins galore

Instrumentation 2

Introduction

GCC & plugins

Instrumentation 1

Instrumentation 2

Structure Constification (CONSTIFY)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

u n s i g n ed int i ; tree var ;F O R _ E A C H _ L O C A L _ D E C L ( cfun , i , var ) {tree type = TREE_TYPE ( var );if ( is_global_var ( var ))continue ;if ( TREE_CODE ( type ) != RECORD_TYPE )continue ;if (! TYPE_READONLY ( type ) || ! C _ T Y P E _ F I E L D S _ R E A D O N L Y ( type ))c o nt i n u e ;if (! T Y P E _ C O N S T I F Y _ V I S I T E D ( type ))c o nt i n u e ;error_at ( D E C L _ S O U R C E _ L O C A T I O N ( var ) ," constified variable % qE cannot be local " ,var );}
mm/shmem.c:1371:30: error: constified variable ’bad_file_operations’ cannot be local

PaX - gcc plugins galoreIntroduction

GCC & plugins

Instrumentation 1

Instrumentation 2

Latent Entropy Extraction (LATENT_ENTROPY)

Overview

I Goal: extract entropy from kernel state during bootI Inspired by https://factorable.net/
I USENIX Security Symposium, August 2012
I Problem: much less entropy after boot than needed
I Result: vulnerable RSA and DSA keys used for SSH/TLS
I Some fixes in Linux but can we do better?

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

Latent Entropy Extraction (LATENT_ENTROPY)LATENT_ENTROPY 2012
I Idea: compute a hash-like function embedded in the control

flow graph of kernel boot code

I Similar and also simpler approach already in Phrack 66
I Insert a random combination of ADD/XOR/ROL insns into

every basic block

I Mix end state into a global variable in the function epilogues
I Feed global variable (entropy) into the kernel entropy pools

after each initcall

I Entropy is not actually accounted for until someone

cryptanalyzes this whole thing :)I More info on our mailing list
PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

Latent Entropy Extraction (LATENT_ENTROPY)LATENT_ENTROPY 2013
I Major change: keep gathering entropy after init
I During fork: fd table and vma list copying (variable loops)
I Module init
I All irq and softirq handlers (lots of loops)
I Would be nice to use a percpu variable, but it’s too archdependent to be usable from a plugin

I Still no entropy accounting

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

Latent Entropy Extraction (LATENT_ENTROPY)LATENT_ENTROPYI PLUGIN_START_UNIT callback:
I Fake the declaration of

extern volatile u64 latent_entropy
I Avoids patching in #include everywhere
I PLUGIN_ATTRIBUTES callback: registers latent_entropy

attribute

I Manually instrumented __init section definition, a few

non-init functions

I PLUGIN_PASS_MANAGER_SETUP: registers core instrumentation

logic

I GIMPLE pass, invoked very late
I Avoids interference with other optimizations, DCE in particular
PaX - gcc plugins galoreIntroduction

GCC & plugins

Instrumentation 1

Instrumentation 2

Latent Entropy Extraction (LATENT_ENTROPY)

1
2
3
4
5
6
7
8
9
10
11
12
13

// extern v o l a t i l e u64 l a t e n t _ e n t r o p y
gcc_assert ( TYPE_ PRECISIO N ( l o n g _ l o n g _ u n s i g n e d _ t y p e _ n o d e ) ==64) ;latent_entropy_type = build_qualified_type (long _long_uns igned_ty pe_node , TYPE_QUALS (long_long_unsigned_type_node ) | TYPE_QUAL_VOLATILE );l a t e n t _ e n t r o p y _ d e c l = build_decl ( UNKNOWN_LOCATION , VAR_DECL ,get_ identifie r ( " la tent_ent ropy " ) , l a t e n t _ e n t r o p y _ t y p e ) ;TREE_STATIC ( l a t e n t _ e n t r o p y _ d e c l ) = 1;
TREE_PUBLIC ( l a t e n t _ e n t r o p y _ d e c l ) = 1;
TREE_USED ( l a t e n t _ e n t r o p y _ d e c l ) = 1;
T R E E _ T HI S _ V O L A T I L E ( l a t e n t _ e n t r o p y _ d e c l ) = 1;
DECL_EXTERNAL ( l a t e n t _ e n t r o p y _ d e c l ) = 1;
D EC L_ AR T IF IC IA L ( l a t e n t _ e n t r o p y _ d e c l ) = 1;
DECL_INITIAL ( l a t e n t _ e n t r o p y _ d e c l ) = bui ld_int_cs tu (long _long_un signed_ty pe_node , g e t _ r a n d o m _ c o n s t () ) ;lang_hooks . decls . pushdecl ( l a t e n t _ e n t r o p y _ d e c l ) ;PaX - gcc plugins galoreIntroduction

GCC & plugins

Instrumentation 1

Instrumentation 2

Latent Entropy Extraction (LATENT_ENTROPY)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

static u n s i g n e d int e x e c u t e _ l a t e n t _ e n t r o p y ( void ){basic_block bb ;tree local_entropy ;bb = ENTRY_BLOCK_PTR - > next_bb ;// i n s t r u m e n t each BB with an o p e r a t i o n on the local entropy
while ( bb != EXIT _BLOCK_P TR ) {p e r t u r b _ l o c a l _ e n t r o p y ( bb , local_entropy );bb = bb - > next_bb ;};// mix local entropy into the global entropy v a r i a b l e
p e r t u r b _ l a t e n t _ e n t r o p y ( EXIT_BLOCK_PTR - > prev_bb , local_entropy );}PaX - gcc plugins galoreIntroduction

GCC & plugins

Instrumentation 1

Instrumentation 2

Latent Entropy Extraction (LATENT_ENTROPY)

1
2
3
4
5
6
7
8
9
10
11
12
13
14

static void p e r t u r b _ l o c a l _ e n t r o p y ( basic_block bb , tree
local_entropy ){g i m p l e _ s t m t _ i t e r a t o r gsi ;gimple assign ;tree addxorrol , rhs ;enum tree_code op ;op = get_op (& rhs ) ;addxorrol = f ol d_ bu i ld 2_ lo c ( UNKNOWN_LOCATION , op ,unsigned_intDI_type_node , local_entropy , rhs ) ;assign = g i m p l e _ b u i l d _ a s s i g n ( local_entropy , addxorrol ) ;gsi = g s i _ a f t e r _ l a b e ls ( bb ) ;g s i _ i n s e r t _ b e f o r e (& gsi , assign , GSI_NEW_STMT ) ;update_stmt ( assign ) ;}get_op: PLUS_EXPR, BIT_XOR_EXPR, LROTATE_EXPR

PaX - gcc plugins galoreIntroduction

GCC & plugins

Instrumentation 1

Latent Entropy Extraction (LATENT_ENTROPY)

static int __init s e t _ r e s e t _ d e v i c e s ( char * str ){reset_devices = 1;
return 1;}

PaX - gcc plugins galore

Instrumentation 2

Introduction

GCC & plugins

Instrumentation 1

Instrumentation 2

Latent Entropy Extraction (LATENT_ENTROPY)

1
2
3
4
5
6
7
8
9
10

s e t _ r e se t _ d e v i c e s ( char * str ){long u n s i g n e d int t e m p _ l a t e n t _ e n t r o p y .139;
long u n s i g n e d int local_entropy .138;< bb 3 >:local_entropy .138 _5 = 1 9 7 2 0 1 9 7 6 4 9 5 0 4 3 9 6 2 4 ;< bb 2 >:local_entropy .138 _6 = local_entropy .138 _5 ^986009882475219812;
t e m p _l a t e n t _ e n t r o p y .139 _3 ={ v } latent_e ntropy ;t e m p _l a t e n t _ e n t r o p y .139 _4 = t e m p _ l a t e n t _ e n t r o p y .139 _3 +local_entropy .138 _6 ;latent_entrop y ={ v } t e m p _ l a t e n t _ e n t r o p y .139 _4 ;reset_devices = 1;
return 1;

11
12
13
14
15
16

}

PaX - gcc plugins galoreIntroduction

GCC & plugins

Instrumentation 1

Latent Entropy Extraction (LATENT_ENTROPY)

1
2
3
4
5
6
7
8
9
10
11
12

0 0 0 0 0 0 0 0 0 0 00 0 0 0 0
0:
mov
7:
push
8:
movabs
12:
movl
1c:
mov
1f:
pop
20:
add
23:
mov
2a:
mov
2f:
btsq
35:
retq

PaX - gcc plugins galore< set_reset_devices >:0 x0 (% rip ) ,% rdx# latent_e ntropy% rbp$0x16f10744be1e5dac ,% rax$0x1 ,0 x0 (% rip )# reset_devices% rsp ,% rbp% rbp% rdx ,% rax% rax ,0 x0 (% rip )# laten t_entropy$0x1 ,% eax$0x3f ,(% rsp )Instrumentation 2

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

Kernel Stack Leak Reduction (STACKLEAK/STRUCTLEAK)

Overview
I Goal: reduce lifetime of data on process kernel stacks byclearing the stack on kernel->user transitions

I Per-arch hooks in the low-level kernel entry/exit code
I Moved thread_info off the stack

I Initially blind memset on the entire kernel stack (8 kbytes)
I Too slow (unused part of the stack is cache cold)

I Refinement: detect/clear only the used part of the stack
I Looks for memset pattern from stack bottom to top

I Optimization: check only a certain length (cache line)
I Needs to record stack depth in functions with a big stackframe

I Manual inspection and patching
I Instrumentation by a gcc plugin

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

Kernel Stack Leak Reduction (STACKLEAK/STRUCTLEAK)

STACKLEAK
I Idea: insert function call to pax_track_stack if local frame

size is over a specific limit

I pax_track_stack records deepest used kernel stack pointer
I Problem: frame size info is available at the last RTL pass

only, too late to insert complex code like a function call

I New strategy: instrument every function first and remove

unneeded instrumentation later

I Also finds all (potentially exploitable :) alloca calls

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

Kernel Stack Leak Reduction (STACKLEAK/STRUCTLEAK)

STACKLEAK
I GIMPLE pass: inserts call to pax_track_stack into every

function prologue

I unless alloca is in the first basic block
I alloca is bracketed with a call to pax_check_alloca and

pax_track_stack
I RTL pass: removes unneeded pax_track_stack calls
I if the local frame size is below the limit
I if alloca is not used

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

Kernel Stack Leak Reduction (STACKLEAK/STRUCTLEAK)

STACKLEAK
I Special paths for ptrace/auditing
I Low-level kernel entry/exit paths can diverge forptrace/auditing and leave interesting information on the stack
for the actual syscall code

I Problems: still considerable overhead, races, leaks from asingle syscall still possible

I Solution: dual process kernel stack, one used only for copying

to/from userland

I Needs static analysis to find all local variables whose address issunk into copy*user

I New gcc plugin, LTO

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

Kernel Stack Leak Reduction (STACKLEAK/STRUCTLEAK)STRUCTLEAK
I Goal: forcibly initialize local variables that can be copied touserlandI Prompted by CVE-2013-2141 (do_tkill kernel stack leak)
I Idea: if a local structure variable has __user annotated fields

then forcibly initialize it if it isn’t alreadyI PLUGIN_FINISH_TYPE callback: sets TYPE_USERSPACE oninteresting structure types

I PLUGIN_PASS_MANAGER_SETUP: core instrumentation logic
I GIMPLE pass, invoked early

PaX - gcc plugins galoreIntroduction

GCC & plugins

Instrumentation 1

Kernel Stack Leak Reduction (STACKLEAK/STRUCTLEAK)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

// e n u m a r a t e all local v a r i a b l e s
u n s i g n ed int i ; tree var ;F O R _ E A C H _ L O C A L _ D E C L ( cfun , i , var ) {tree type = TREE_TYPE ( var );if (! a u to _ v a r _ i n _ f n _ p ( var , c u r r e n t _ f u n c t i o n _ d e c l ))continue ;// only care about s t r u c t u r e types
if ( TREE_CODE ( type ) != RECORD_TYPE )c o nt i n u e ;// if the type is of interest , examine the v a r i a b l eif ( TYP E_USERSP ACE ( type ))initialize ( var );}PaX - gcc plugins galore

Instrumentation 2

Introduction

GCC & plugins

Instrumentation 1

Instrumentation 2

Kernel Stack Leak Reduction (STACKLEAK/STRUCTLEAK)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

static void initialize ( tree var ){basic_block bb ;g i m p l e _ s t m t _ i t e r a t o r gsi ;tree initializer ;gimple init_stmt ;// build the i n i t i a l i z e r e x p r e s s i o ninitializer = b u i l d _ c o n s t r u c t o r ( TREE_TYPE ( var ) , NULL );// build the i n i t i a l i z e r stmt
init_stmt = g i m p l e _ b u i l d _ a s s i g n ( var , initializer );gsi = gsi_start_bb ( ENTRY_BLOCK_PTR - > next_bb );g s i _ i n s e r t _ b e f o r e (& gsi , init_stmt , GSI_NEW_STMT );update_stmt ( init_stmt );}PaX - gcc plugins galoreIntroduction

GCC & plugins

Instrumentation 1

Introduction
GCC & plugins
Instrumentation 1
Instrumentation 2
Integer (Size) Overflow Detection (SIZE_OVERFLOW)KERNEXEC/amd64 helper plugin
Backup

PaX - gcc plugins galore

Instrumentation 2

Introduction

GCC & plugins

Instrumentation 1

Instrumentation 2

Integer (Size) Overflow Detection (SIZE_OVERFLOW)

Overview
I Detects integer overflows in expressions used as a size

parameter: kmalloc(count * sizeof...)
I Written by Emese Révfy, extends spender’s old idea
(preprocessor trick)
I Initial set of functions/parameters marked by thesize_overflow function attribute
I Walks use-def chains and duplicates statements using adouble-wide integer type
I SImode/DImode vs. DImode/TImodeI Special cases: asm(), function return values, constants(intentional overflows), memory references, type casts, etc
I More in our blog
PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

Integer (Size) Overflow Detection (SIZE_OVERFLOW)SIZE_OVERFLOW 2012
I PLUGIN_ATTRIBUTES callback: size_overflow attribute,takes arbitrary arguments (size parameter index)

I Only a handful of functions are marked by hand
I Hash table lookup for the rest (could be automated with LTO)
I GIMPLE pass: handle_function enumerates all function

calls looking for the size_overflow attribute (or hash table)

I handle_function_arg starts the real work
I Manually walks the use-def chain of the given function

argument

I Walk forks on binary/ternary operations and phi nodes
I Walk stops at asm/call stmts, function parameters, globals,

memory references, constants, etc

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

Integer (Size) Overflow Detection (SIZE_OVERFLOW)SIZE_OVERFLOW 2012
I When a walk stops, stmt duplication begins
I New variable is created with signed_size_overflow_type
I DImode or TImode (signed)
I When stmt duplication reaches the original function call, theduplicated result is bounds checked

I Against TYPE_MAX_VALUE/TYPE_MIN_VALUE
I Optimization: check omitted if the walk did not find any stmt

that could cause an overflow

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

Integer (Size) Overflow Detection (SIZE_OVERFLOW)SIZE_OVERFLOW 2013
I Range checks on certain narrowing casts to catch integer

truncation bugs

I Caught various info leaks
I CVE-2013-0914 (sa_restorer leak between userland processes)
I CVE-2013-2141 (do_tkill kernel stack leak)
I New IPA pass to be able to walk across functions within atranslation unit
I Spender’s idea: combine with STACKLEAK (stack poisoning)and USERCOPY (check poison in data to be copied touserland) and trinity (fuzzing)
I Tons of info leak bugs triggered, not always trivial find thesource of the leak (kernel stack → kernel heap → userland)

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

KERNEXEC/amd64 helper plugin

Overview
I Goal: prevent executing userland code on amd64
I Idea: set most significant bit in all function pointers before

dereference

I Userland addresses become non-canonical ones, GPF on any

dereference

I GIMPLE pass: handles C function pointers(execute_kernexec_fptr)

I RTL pass: handles function return values(execute_kernexec_retaddr)

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

KERNEXEC/amd64 helper plugin

KERNEXEC/amd64 helper plugin

I Two methods: bts vs. or (reserves %r10 for bitmask)
I Compatibility vs. performance
I Special cases: vsyscall, assembly source, asm()
I kernexec_cmodel_check to exclude code in vsyscall sections
I Manual verification/patching
I GIMPLE pass to reload r10 when clobbered by asm()

PaX - gcc plugins galore

GCC & plugins

Introduction

Instrumentation 1

Instrumentation 2

Backup

LTO plans
I CONSTIFY: find all non-constifiable types/variables
I REFCOUNT: find all non-refcount atomic_t/atomic64_t

uses

I SIZE_OVERFLOW: walk use-def chains across function calls,

eliminate the hash table

I STACKLEAK: find all local variables whose address sinks into

copy*user
I USERCOPY: find all kmalloc-* slab allocations that sink

into copy*user

PaX - gcc plugins galorehttp://pax.grsecurity.net
http://grsecurity.net
irc.oftc.net #pax #grsecurity