source analysis for security

54
Source Analysis for Security Trent Jaeger March 29, 2004

Upload: tara

Post on 08-Jan-2016

34 views

Category:

Documents


3 download

DESCRIPTION

Source Analysis for Security. Trent Jaeger March 29, 2004. Example 1. Example 2. get_free_buffer (struct stripe_head *sh, …) { struct buffer_head *bh; unsigned long flags; save_flags(flags); cli(); if ((bh = sh->buffer_pool) == NULL) return NULL; sh->buffer_pool – bh->b_next; - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Source Analysis for Security

Source Analysis for Security

Trent Jaeger

March 29, 2004

Page 2: Source Analysis for Security

Example 1

sys_fcntl(int fd, ...) {struct file *filp; ...filp = fget(fd); ...err = security_ops->file_ops->fcntl(filp, ...); ...do_fcntl(fd, ...); ...

}

do_fcntl(int fd, ...) { ...err = fcntl_setlk(fd, ...); ...

}

fcntl_setlk(int fd, ...) { ...struct file *filp; ...filp = fget(fd); /* is this the one checked in sys_fcntl? */

Page 3: Source Analysis for Security

Example 2

get_free_buffer(struct stripe_head *sh, …) {struct buffer_head *bh;unsigned long flags;

save_flags(flags);cli();if ((bh = sh->buffer_pool) == NULL)

return NULL;sh->buffer_pool – bh->b_next;bh->b_size = b_size;restore_flags(flags);return bh;

}

Page 4: Source Analysis for Security

Example 3

sys_fcntl(int fd, ...) {err = security_ops->file_ops->fcntl(filp, ...); ...do_fcntl(fd, ..., filp); ...

}

do_fcntl(int fd, ..., struct file *filp) { ...case F_SETLEASE:

fcntl_setlease(fd, filp, ...); ...case F_SETOWN:

err = security_ops->file_ops->set_fowner(filp, ...); ... if (err) ... break; filp->f_owner.pid = arg; filp->f_owner.uid = current->uid; filp->f_owner.euid = current->euid; ...}

Page 5: Source Analysis for Security

Example 3 (con’t)

fcntl_setlease(int fd, struct file *filp, ...) { ... if (my_before != NULL) { error = lease_modify(my_before, arg, fd, filp);

...} ...}

lease_modify(..., int fd, struct file *filp, ...) { ... if (arg == F_UNLCK) { /* should these be f_setowner auth'd ? */ filp->f_owner.pid = 0; filp->f_owner.uid = 0; filp->f_owner.euid = 0; filp->f_owner.signum = 0;}

Page 6: Source Analysis for Security

Example 4

int notify_change(struct dentry * dentry, struct iattr * attr) { struct inode *inode = dentry->d_inode; …if (inode->i_op && inode->i_op->setattr) {

error = security_inode_setattr(dentry, attr); if (!error)

error = inode->i_op->setattr(dentry, attr);…

}

Page 7: Source Analysis for Security

Find Software Bugs

Education– Difficult to know how code will be used

Testing– Misses many code paths, time consuming

Manual Inspection– Tedious and error prone

Compiler checking– Context independent

4GL– Incomplete and don’t know how source code will be used

Assurance– Extremely costly and complex – what do we do about existing code?

Page 8: Source Analysis for Security

Limited Source Code Analysis

Source code is the level security is defined– Problems manifest in errors in code (although design can

be a problem too) Compilers can check for various properties

– Rules on program source Programmers can express some properties

– Semantic properties– Must specify correctly (no/few false negatives)– Must not be too conservative (few false positives)– Like to be robust with code changes

Page 9: Source Analysis for Security

Source Code Analysis

Covert source code into a model Convert property into a computation on

model Report positive cases (violate/meet property) Determine if cases are true or false Resolve true cases Refine model or property and repeat

Page 10: Source Analysis for Security

Some Properties

Never/always do X– Never use floating point in kernel

Do X rather than Y Always do X before/after Y

– LSM mediation (Example 1) Never do X before/after Y In situation X, do (not) Y

– Re-enable disabled interrupts (Example 2) In situation X, do Y rather than X

Page 11: Source Analysis for Security

Program Models

Abstract Syntax Tree Control flow Data flow Def-use chain Aliases Type constraints …

Page 12: Source Analysis for Security

Abstract Syntax Tree

Func_declSys_fcntl

var_declStruct file *filp

Expr_stmt=

Var_declfilp

call_declFget(fd)

Expr_stmt=

Var_declerr

Cmpd_stmtSecurity_op

call_decldo_fcntl

Func_declDo_fcntl

Expr_stmt=

Var_declerr

Call_stmtFcntl_setlk(fd)

Func_declFcntl_setlk

var_declStruct file *filp

Expr_stmt=

Var_declfilp

call_declFget(fd)

cmpd_stmtUse filp

Page 13: Source Analysis for Security

Control Flow (Interprocedural)

Func_declSys_fcntl

var_declStruct file *filp

Expr_stmt=

Var_declfilp

call_declFget(fd)

Expr_stmt=

Var_declerr

Cmpd_stmtSecurity_op

call_decldo_fcntl

Func_declDo_fcntl

Expr_stmt=

Var_declerr

Call_stmtFcntl_setlk(fd)

Func_declFcntl_setlk

var_declStruct file *filp

Expr_stmt=

Var_declfilp

call_declFget(fd)

cmpd_stmtUse filp

Page 14: Source Analysis for Security

Control Flow (Intraprocedural)

Func_declSys_fcntl

var_declStruct file *filp

Expr_stmt=

Var_declfilp

call_declFget(fd)

Expr_stmt=

Var_declerr

Cmpd_stmtSecurity_op

call_decldo_fcntl

Func_declDo_fcntl

Expr_stmt=

Var_declerr

Call_stmtFcntl_setlk(fd)

Func_declFcntl_setlk

var_declStruct file *filp

Expr_stmt=

Var_declfilp

call_declFget(fd)

cmpd_stmtUse filp

Page 15: Source Analysis for Security

Data Flow

Func_declSys_fcntl

var_declStruct file *filp

Expr_stmt=

Var_declfilp

call_declFget(fd)

Expr_stmt=

Var_declerr

Cmpd_stmtSecurity_op

call_decldo_fcntl

Func_declDo_fcntl

Expr_stmt=

Var_declerr

Call_stmtFcntl_setlk(fd)

Func_declFcntl_setlk

var_declStruct file *filp

Expr_stmt=

Var_declfilp

call_declFget(fd)

cmpd_stmtUse filp

Page 16: Source Analysis for Security

Def-Use

Func_declSys_fcntl

var_declStruct file *filp

Expr_stmt=

Var_declfilp

call_declFget(fd)

Expr_stmt=

Var_declerr

Cmpd_stmtSecurity_op

call_decldo_fcntl

Func_declDo_fcntl

Expr_stmt=

Var_declerr

Call_stmtFcntl_setlk(fd)

Func_declFcntl_setlk

var_declStruct file *filp

Expr_stmt=

Var_declfilp

call_declFget(fd)

cmpd_stmtUse filp

Page 17: Source Analysis for Security

Property Models

Finite State Automata– Start Operation – Disable Interrupts– Enable Interrupts – End Operation

Type Constraints– Unchecked type– Checked type– Expect checked type

disable

disableEnd Openable

double_enable double_disableExit w/ disabled

enable

Page 18: Source Analysis for Security

CQUAL Static Analysis

CQUAL is a type-based static analysis tool from UC Berkeley

Enables qualification of types, analogous to const

Enables verification that the type passed to a function is the type expected

Used previously for verification of format string vulnerabilities

– Wagner’s group at UC Berkeley in USENIX Security 2001

Page 19: Source Analysis for Security

CQUAL Principles

Interprocedural control flow– do_fcntl calls fcntl_getlk

Def-Use data flow– Assignments tracked back to def where type is declared– Type inference

Variables have type restrictions– Cannot assign a variable to another of an incompatible type– Cannot send a variable as a parameter to a function unless

its type is compatible

Page 20: Source Analysis for Security

CQUAL Approach

Initializing Function

Initializing Function

Authorizing Function

Controlled Function

Controlled Function

X

unchecked inode i

checked inode i

checkedinode i

require

Page 21: Source Analysis for Security

Identify Declarations

foo(){struct inode * unchecked i; /*declaration*/...security_ops->inode_ops->check(i); /*check*/...map = i->i_mapping; /*local controlled op*/...map->readpage(i); /* function call */}

readpage(struct inode *j) {...} /* subroutine */

Page 22: Source Analysis for Security

Identify Controlled Params

foo(){struct inode * unchecked i; /*declaration*/...security_ops->inode_ops->check(i); /*check*/...map = i->i_mapping; /*local controlled op*/...map->readpage(i); /* function call */}

readpage(struct inode * checked j) {...} /* subroutine */

Page 23: Source Analysis for Security

Create “Checked” Variable

foo(){struct inode * unchecked i; /*declaration*/struct inode * checked i2;...security_ops->inode_ops->check(i); /*check*/i2 = (struct inode * checked) i;...map = i2->i_mapping; /*local controlled op*/...map->readpage(i2); /* function call */}

readpage(struct inode * checked j) {...} /* subroutine */

Page 24: Source Analysis for Security

Verify Local Controlled Ops

foo(){struct inode * unchecked i; /*declaration*/struct inode * checked i2;...security_ops->inode_ops->check(i); /*check*/i2 = (struct inode * checked) i;...map = i2->i_mapping; /*local controlled op*/...map->readpage(i2); /* function call */}

readpage(struct inode * checked j) {...} /* subroutine */

Page 25: Source Analysis for Security

Find Assignments to ‘Checked’

foo(){struct inode * unchecked i, * unchecked i3; /*declaration*/struct inode * checked i2, * checked i4;struct dentry * unchecked dentry;...security_ops->inode_ops->check(i); /*check*/i2 = (struct inode * checked) i;i2 = i3; /* unchecked to checked -- fail */i2 = i4; /* checked to checked -- OK */i2 = (struct inode * unchecked) 0xc0000000; /* fail */map->readpage(dentry->d_inode); /* infer checked -- wrong */...}

Page 26: Source Analysis for Security

Verify Interprocedural Paths

foo(){struct inode * unchecked i; /*declaration*/struct inode * checked i2;...security_ops->inode_ops->check(i); /*check*/i2 = (struct inode * checked) i;...map = i2->i_mapping; /*local controlled op*/...map->readpage(i2); /* function call */}

readpage(struct inode * checked j) {...} /* subroutine */

Page 27: Source Analysis for Security

Verify Interprocedural Paths

bar(){struct inode * unchecked i; /*declaration*/...map = i->i_mapping; /*local controlled op*/...map->readpage(i); /* function call */}

readpage(struct inode * checked j) {...} /* subroutine */

CQUAL will detect "type error" on 'i'

Page 28: Source Analysis for Security

Find Example 1 Error

sys_fcntl(int fd, ...) {struct file unchecked *filp; ...filp = fget(fd); ...err = security_ops->file_ops->fcntl(filp, ...); ... /* new checked filp2 */do_fcntl(fd, ...); ...}

do_fcntl(int fd, ...) { ...err = fcntl_setlk(fd, ...); ...}

fcntl_setlk(int fd, ...) { ...struct file unchecked *filp; ...filp = fget(fd); /* is this the one checked in sys_fcntl? */

Page 29: Source Analysis for Security

Sensitivity: Flow and Context

Flow-sensitivity– The order of statements in a function matters– CQUAL is not flow-sensitive– Must create new ‘checked’ variable– Must use GCC to verify intraprocedural paths– Must use GCC to find reassignments after ‘checked’

Context-sensitivity– A function is treated differently depending on calling site– CQUAL is not context-sensitive– If two functions call the same descendant must have the

same requirements in CQUAL

Page 30: Source Analysis for Security

CQUAL Postscript

Flow-sensitive CQUAL– Initial performance was not good

Field level data flow– Extensions at UC Berkeley

We switched to new tool (JaBA)– Interprocedural control flow– Intraprocedural control flow (flow-sensitive)– Context-sensitive– Variable and field-level data flow– Replicated analyses of Example 1 and 3 while preventing

false positives of Example 4

Page 31: Source Analysis for Security

Meta-compilation

Compilers– Have program source– Can implement straightforward rules for source

checking– Lack domain semantics of programs

Programmers– Have domain semantics of programs– Need a means to express these semantics such

that they can be checked

Page 32: Source Analysis for Security

Meta-compilation

Model– GCC abstract syntax tree– Compute interprocedural control flow graph– Compute intraprocedural control flow graph

Properties– Finite state automata – Generate extensions from specification

Computation– FSA state transitions are represented by patterns– Find syntactic patterns in code– Build intraprocedural paths with relevant state changes– For each path, compute resultant state transitions

Page 33: Source Analysis for Security

Properties: Meta Language (metal)

{ #include “linux-includes.h” }

sm check_interrupts {

// Variables used in patterns

decl { unsigned } flags;

// Patterns to specify enable/disable fns

pat enable = { sti(); }

| { restore_flags(flags); } ;

pat disable = { cli() };

// States – implicit initial state

is_enabled: disable is_disabled

enable { err(“double enable”); } ;

is_disabled: disable { err(“double disable”); }

| $end of path$ { err(“exiting w/ intr disabled”); }

disable

disableEnd Openable

double_enable double_disableExit w/ disabled

enable

Page 34: Source Analysis for Security

Example 2 Processing

get_free_buffer(struct stripe_head *sh, …) {struct buffer_head *bh;unsigned long flags;

save_flags(flags);cli();if ((bh = sh->buffer_pool) == NULL)

return NULL;sh->buffer_pool – bh->b_next;bh->b_size = b_size;restore_flags(flags);return bh;

}

disable

enableend of path

end of path err

Page 35: Source Analysis for Security

Meta-Compilation System

Compile Metal State Machine (SM) with mcc Dynamically link SM into xg++

– Compile-time, command line flag

It is “pushed down” “both paths”– Paths are built and checked against SM

All paths vs one pass (flow-sensitive vs. insensitive)– Prune paths that reach join in same state– Fixed point: loop until reach all possible paths

Page 36: Source Analysis for Security

Prune Paths

disable

enable

Choice of paths doesnot matter, so only oneneeds to be kept

Page 37: Source Analysis for Security

Assertion Checking – Side Effects

{ #include “linux-includes.h” }sm Assert flow-insensitive {

// Match expressionsdecl { any } expr, x, y, z;decl { any_call } any_fcall;decl { any_args } args;

// States: find asserts and detect side effectsstart: { assert(expr); }

{mgk_expr_recurse(expr, in_assert); } ;

in_assert: { any_fcall(args) } { err(“fn call”); }

| { x = y } { err(“assignment”); }| { z++ } { err(“post-increment”); }| { z-- } { err(“post-decrement”); }

Page 38: Source Analysis for Security

xgcc Extension (PLDI 2002)

Match patterns to statements– Identify state transitions

Compute intraprocedural paths– Prune those that cannot matter (no state changes)

Combine intraprocedural paths into complete paths– Analysis instance based on a transition from a start state– Paths are generated for each instance – Assignments result in creating a new instance that is a copy

Page 39: Source Analysis for Security

Checking memory management

unknown

allocation

null not-null

Conditional check on ptrimplying null

Conditional check on ptrimplying not null

freed

free

overwrite

stop

dereference

free, dereference

end path

free,dereference

free

Page 40: Source Analysis for Security

Checking memory management

Intraprocedural control flow– Distinguish between paths with null and non-null pointers

Interprocedural control flow– “Global analysis” done in PLDI by combining intraprocedural paths

Data flow– None, pure syntactic comparison– Assignment does result in replication of state machine for assigned

variable Finds bugs, but does not guarantee absence

– No track of assignment to a structure field– No Aliases

False positives– Syntactic path-sensitivity keeps them moderate

Page 41: Source Analysis for Security

Other Example Analyses

Example 3 – (check fcntl and set_fowner)– If we know the required authorizations for each operation,

we can define the states of these ops– Don’t know this (tedious to specify)– We use a consistency analysis (ACM TISSEC, May 2004)

Example 4 – (distinguish between dentryinode and inode)

– Specify that { inode = dentryinode } links inode state with dentry state

– Note that this does not compute from 1st principles, so manual effort is required to ensure it is correct

Page 42: Source Analysis for Security

xgcc Postscript

Lots of papers on finding bugs using these techniques– Lots of simple errors in code

Other aspects – Automating annotation– Statistical analysis

Coverity, Inc.

Page 43: Source Analysis for Security

GCC Architecture

Compilers for C, C++, Java Consists of a sequence of compilation steps

all of which can be hooked (3.0 and greater) Eventually, has a single representation of all

(gimple) Then converts to Register Transfer

Language (RTL) at which point all typing is lost

Page 44: Source Analysis for Security

MOPS

Aim to provide a ‘sound’ analysis architecture– That is, no false negatives for their model

Program model– Pushdown automata of program

Property model– Finite state automata of security property– Temporal properties

Like xgcc, there is no real data flow analysis Unlike xgcc, language for properties is not defined

Page 45: Source Analysis for Security

Formal Basis

FSA M accepts a language of security property violations B– All operation sequences that obey M violate security property

PDA P accepts all feasible program traces T– Traces are interprocedural combination of intraprocedural control

flow paths– Note that traces are control flow representation

Problem: Decide if any trace violates security property– As whether T B = null– Represented by L(M) L(P) = null– Intersection of PDA and FSA can be computed efficiently– Note that TL(P), so some infeasible traces are in L(P)

Page 46: Source Analysis for Security

Example 2

disable

disableEnd Openable

double_enable double_disableExit w/ disabled

enable

get_free_buffer(struct stripe_head *sh, …) {struct buffer_head *bh;unsigned long flags;

save_flags(flags);cli();if ((bh = sh->buffer_pool) == NULL)

return NULL;sh->buffer_pool – bh->b_next;bh->b_size = b_size;restore_flags(flags);return bh;

}

Page 47: Source Analysis for Security

Example 1

check

use

unmediated

assignsys_fcntl(int fd, ...) {struct file *filp; ...filp = fget(fd); ...err = security_ops->file_ops->fcntl(filp, ...); ...do_fcntl(fd, ...); ...

}

do_fcntl(int fd, ...) { ...err = fcntl_setlk(fd, ...); ...

}

fcntl_setlk(int fd, ...) { ...struct file *filp; ...filp = fget(fd); /* is this the one checked in sys_fcntl? */

assign

useuse

Unassigned Use unmediated

assign

check

zero, free

Page 48: Source Analysis for Security

MOPS Distinguishing Features

Modularity– Can create a hierarchy of FSAs– Haven’t seen this used…

Pattern variables– “bound to any expression that satisfies context constraints”– Difference from xgcc patterns?

Modeling– PDA and FSA a combined into a composite PDA that

accepts L(M) L(P) – Can determine all the FSA states that an instruction can be

executed in

Page 49: Source Analysis for Security

Modeling OS for MOPS

Find all kernel variables that affect security– Done manually

Determine the states in the FSA for each– Done manually

Determine transitions between states– Transition in FSA– Automated state space explorer – Execute all paths and create transitions

automatically

Page 50: Source Analysis for Security

Setuid

Variable euid determines privilege Euid can be modified by several functions:

– setuid, seteuid, setreuid, setresuid Value of euid depends on value of other variables on

input to these system calls – ruid, suid– cap_effective, cap_permitted– Are found manually

Transitions indicate system calls that lead to changes in variables

Page 51: Source Analysis for Security

Impact of Soundness

Control flow sound– Combination of PDA and FSA is sound– Context-sensitive– Different than xgcc?

Construction of FSA has manual steps– Identification of variables– Identification of system calls that impact variables– Could these be automated? Data flow…– FSA states are defined manually– Support for finding transitions automatically once we know

the system calls that matter – different than xgcc? Construction of PDA is automated

– Different from xgcc?

Page 52: Source Analysis for Security

Dataflow

Find variables– Manually determine syntactic matches

Definitions Dependencies/States

– Manually determine syntactic dependencies Assignments Parameters Structure members Operations that change state

Values associated with variables– Assume different for each variable; same for struct

Fget(fd) returns a different fd Dentry->inode is same for dentry

Ignore aliases– Could detect in thread; Not usually there

Multiple possible assignments

Page 53: Source Analysis for Security

Classification of Analysis Tools

Specialized checkers (syntactic bugs)– Lint, ITS4, JTest

Annotation checkers (buffer overflows, parse errors)– LCLint, CQual

Automata checkers (temporal bugs – no data flow)– xgcc/metal, MOPS

Control and data flow for custom analyses (temporal ++)– PREfix (C/C++), JaBA (Java)

Predicate Refinement (driver – small program -- verification)– SLAM, MAGIC

Page 54: Source Analysis for Security

More Analysis

Runtime Analysis– Consistency, buffer overflows

Policy Analysis– SELinux

Intrusion Detection– Represent feasible paths through a program