Software
This presentation is the property of its rightful owner.
Sponsored Links
1 / 44

Software fault isolation with API integrity and multi-principal modules PowerPoint PPT Presentation


  • 91 Views
  • Uploaded on
  • Presentation posted in: General

Software fault isolation with API integrity and multi-principal modules Yandong Mao, Haogang Chen ( MIT CSAIL ), Dong Zhou ( Tsinghua University IIIS ), Xi Wang, Nickolai Zeldovich , Frans Kaashoek ( MIT CSAIL ). Kernel security is important. Kernel is fully privileged

Download Presentation

Software fault isolation with API integrity and multi-principal modules

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Software fault isolation with api integrity and multi principal modules

Software fault isolation with API integrity and multi-principal modules

Yandong Mao, Haogang Chen (MIT CSAIL),

Dong Zhou (TsinghuaUniversity IIIS),

Xi Wang, NickolaiZeldovich, FransKaashoek (MIT CSAIL)


Software fault isolation with api integrity and multi principal modules

Kernel security is important

  • Kernel is fully privileged

  • Kernel compromises are devastating

    • Remote attacker takes control over the whole machine

    • Local user gains root privilege


Software fault isolation with api integrity and multi principal modules

Linux kernel is vulnerable

  • Vulnerabilities in Linux are routinely discovered

    • CVE 2010: 145 vulnerabilities in Linux kernel

  • Many exploits attack kernel modules

    • 67% of Linux kernel vulnerabilities (CVE 2010)

  • This talk focuses on vulnerabilities in kernel modules


Software fault isolation with api integrity and multi principal modules

Threat

  • Module programmer makes mistake

  • Attacker exploits mistake to mount attacks

  • Example: buffer overflow, set current UID to root

Module

Privilege escalation!

Kernel memory

Module memory

UID


Software fault isolation with api integrity and multi principal modules

One approach: type safe languages

  • Write kernel and modules in Java, C#

  • No reference to UID object => cannot directly change UID

    • Attacker cannot synthesize references

Module

Most kernels are not written

in type safe language!

UID


Software fault isolation with api integrity and multi principal modules

Software Fault Isolation (SFI[SOSP93])

Module

Can not bypass SFI check

char *p = 0xf7;

sfi_check_memory(p);

*p = 0;

SFI Runtime

void sfi_check_memory(p) {

if p not in “Module memory”

stop_module();

}

Module memory

UID


Software fault isolation with api integrity and multi principal modules

Memory safety is insufficient

for stopping attacks!

  • Challenge: module needs to call kernel functions

Core Kernel

Spin_module

  • void spin_lock_init(spinlock_t*lock) {

    lock->v = 0;

    }

spinlock_tmylock;

spin_lock_init(&mylock);

Module memory

UID


Software fault isolation with api integrity and multi principal modules

Problem: API abuse

  • Attacker tricks fully-privileged kernel code to overwrite UID

Core Kernel

Spin_module

  • void spin_lock_init(spinlock_t*lock) {

    lock->v = 0;

    }

spin_lock_init(&cur_proc->uid);

Privilege escalation!

Module memory

UID


Software fault isolation with api integrity and multi principal modules

Challenge: lack of API integrity

  • Kernel APIs are not written defensively

    • Assume the calling module to obey implicit rules

      • Do not check arguments, permissions, etc

  • Problem: modules cannot be trusted to follow rules

    • Module can trick kernel into performing unexpected actions

  • Ideal system would enforce rules for kernel API

    • Analogy: system call code assumes nothing about caller, checks every assumption


Software fault isolation with api integrity and multi principal modules

State of the art

for protecting APIs

  • SFI[SOSP93]: memory safety

  • XFI[OSDI06]: no argument checks

  • BGI[SOSP09]: manually wrap functions, make kernel defensive when kernel code invokes callbacks

    • Error-prone and time-consuming

    • Works if kernel code is well-structured (not Linux)


Software fault isolation with api integrity and multi principal modules

Our approach: annotation language

  • Helps enforce two types of API integrity:

    • Argument integrity: programmer controls what arguments a module can pass to functions

    • Callback integrity: kernel invokes callback only if the module could have invoked callback directly

  • Allows programmers to specify principals for privilege separation within a module

  • Less error-prone than manual wrapping, applicable to complex APIs such as those in Linux


Software fault isolation with api integrity and multi principal modules

Contributions

  • LXFI: software fault isolation system for Linux kernel modules

  • Annotation language for

    • Argument integrity

    • Callback integrity

    • Privilege separation within a module

  • Evaluation

    • Few annotations for 10 Linux kernel modules

    • Stop three real exploits

    • 2-4X CPU overhead for netperf


Software fault isolation with api integrity and multi principal modules

Goals for annotation language

  • Enforce argument integrity, callback integrity and privilege separation within a module

  • Minimize programmer effort, e.g.:

    • Few annotations

    • Avoid data structure and API changes

  • Compatible with C


Software fault isolation with api integrity and multi principal modules

Preventing module exploits

Programmer annotates core kernel

If annotations capture all implicit rules, compromised module cannot violate rules to gain additional privileges.

Using compiler plugins;

Provide safe default: reject a module if it calls an unannotated API

LXFI translatesannotationsto runtime checks

Compile time

Consulting a dynamic table of capabilities for each module

LXFI performs checks

Runtime


Software fault isolation with api integrity and multi principal modules

Design of annotation language

  • Argument integrity annotations

    • Using the spin_lock_initexample

  • Callback integrity annotations

    • Not discussed; see paper

  • Privilege separation annotations

    • Using dm_crypt(real Linux kernel module)


Software fault isolation with api integrity and multi principal modules

Enforce argument integrity

  • spin_lock_init: three annotations are required


Software fault isolation with api integrity and multi principal modules

Example: enforce argument integrity for spin_lock_init

Core Kernel

Spin_module

void spin_lock_init(spinlock_t*lock)

pre(check(write(lock, sizeof(spinlock_t)))

capability table

write(mylock, 8)

LXFI Runtime

  • lxfi_check_write(mylock, 8);

    spin_lock_init(mylock)

……

  • lxfi_check_write(&cur_proc->uid, 8);

    spin_lock_init(&cur_proc->uid)

……

Privilege escalation prevented

Module memory

UID


Software fault isolation with api integrity and multi principal modules

Where does the capability come from?

  • Granted on allocation

  • Two more annotations are required


Software fault isolation with api integrity and multi principal modules

Example: grant spinlock

Core Kernel

Spin_module

void *kmalloc(size)

post(copy(write(return, size))

spinlock_t *mylock = kmalloc(8);

lxfi_copy_write(mylock, 8);

……

LXFI Runtime

capability table

write(mylock, 8)


Software fault isolation with api integrity and multi principal modules

What happens when memory is freed?

  • Need to revoke capability to safely reuse memory

  • Strawman: revoke capability from caller

    • Insufficient! Other modules may have copies of capability

No other copies of the capability remain


Software fault isolation with api integrity and multi principal modules

Example: safely free a spinlock

Core Kernel

Spin_module

void kfree(void *p)

pre(transfer(write(p, no_size)))

LXFI Runtime

  • lxfi_transfer_write(mylock, -1);

    kfree(mylock);

……

capability table

write(mylock, 8)

other_module

capability table

write(mylock, 8)


Software fault isolation with api integrity and multi principal modules

Why is spin_module able to call spin_lock_init, kmalloc, kfree?

  • Call capability

  • Granted initially according to the module’s symbol table

    • Trust module author not to call unnecessary functions

  • Dynamically granted when a callback function is passed


Software fault isolation with api integrity and multi principal modules

Core Kernel

Spin_module

void *kmalloc(size)

post(copy(write(return, size))

void spin_lock_init(spinlock_t *lock)

pre(check(write(lock, sizeof(spinlock_t)))

void kfree(void *p)

pre(transfer(write(p, no_size))

capability table

call(kmalloc)

call(spin_lock_init)

call(kfree)

LXFI Runtime

……

spinlock_t *mylock = kmalloc(8);

lxfi_copy_write(mylock, 8);

lxfi_check_write(mylock, 8);

spin_lock_init(mylock)l

lxfi_check_write(&cur_proc->uid, 8);

spin_lock_init(&cur_proc->uid);

lxfi_transfer_write(mylock, -1);

kfree(mylock);

……

……

……


Software fault isolation with api integrity and multi principal modules

No way for compromised spin_module to gain root privilege

  • SFI ensures memory safety

  • Call capabilities ensure only 3 functions are allowed

  • None of the functions can modify UID because:

    • kmalloc never modifies allocated memory

    • spin_lock_init can only be called with writable memory (from kmalloc)

    • kfree ensures no capabilities remain after free

  • spin_module can not modify UID!


Software fault isolation with api integrity and multi principal modules

Privilege separation within a module

  • dm_crypt: transparent encryption service for block devices

  • This example requires a third type of capability

Pass argument a as type t


Software fault isolation with api integrity and multi principal modules

Privilege separation

write(“/etc/secret.txt”, “foo”)

User space

Kernel space

Core Kernel

intbdev_write(block_device *dev,

const char * data, …)

pre(check(ref(block_device), dev)

write(enc_disk, “foo”, …)

dm_crypt

capability table

ref(block_device, enc_disk->bdev)

Writing block device does not require writing to memory of enc_disk->bdev.

LXFI Runtime

  • lxfi_check_ref(block_device, enc_disk->bdev)

    bdev_write(enc_disk->bdev, E(“foo”), …)


Software fault isolation with api integrity and multi principal modules

Privilege separation

read(…)

User space

Kernel space

Core Kernel

intbdev_write(block_device *dev,

const char * data, …)

pre(check(ref(block_device), dev)

dm_crypt

capability table

ref(block_device, enc_disk->bdev)

ref(block_device, enc_usb->bdev)

capability table

ref(block_device, enc_disk->bdev)

capability table

ref(block_device, enc_usb->bdev)

LXFI Runtime

Decrypt

  • lxfi_check_ref(block_device, enc_disk->bdev)

    bdev_write(enc_disk->bdev, “/etc/pwd”, “foo”)

/etc/pwd: rootpwd=foo


Software fault isolation with api integrity and multi principal modules

How to define principals

  • Associate a principal with every instance a module supports (e.g. block device in dm_crypt)

  • Problem: how to specify and name principals?

    • Recall goal: minimize changes to existing data structures

  • Idea: re-use address of data structure as the name of the principal

    • Can typically identify principal from one of the function arguments


Software fault isolation with api integrity and multi principal modules

Specifying principals


Software fault isolation with api integrity and multi principal modules

Privilege separation

User space

Kernel space

Core Kernel

structdm_type {

int (*map)(structdm_target *di);

principal(di)};

lxfi_set_princ(enc_usb)

dm_crypt.map(enc_usb)

dm_crypt

capability table

write(enc_disk->bdev, 100)

capability table

write(enc_usb->bdev, 100)

LXFI Runtime

Decrypt

  • lxfi_check_write(enc_disk->bdev, 100)

    bdev_write(enc_disk->bdev, “/etc/pwd”, “foo”)

/etc/pwd: rootpwd=foo


Software fault isolation with api integrity and multi principal modules

Principal name aliasing

  • Problem: Kernel identifies a LXFI principal by multiple addresses

  • Insert code into module to create alias

  • The same principal now has multiple names

inte1000_probe(structpci_dev *pcidev) {

structnet_device *ndev= alloc_etherdev(...);

ndev->pcidev = pcidev;

...

}

int e1000_xmit(structnet_device *dev) {

…}

lxfi_princ_alias(pcidev, ndev);


Software fault isolation with api integrity and multi principal modules

Other annotation language features

Save annotation effort for complex objects that need multiple capabilities

Express conditional action such as grant a privilege if return value is OK

Global:principal with full privilige

Shared:principal with minimal privilege


Software fault isolation with api integrity and multi principal modules

Implementation

  • Linux 2.6.36, x64, single-core

  • gccplugin: kernel rewriting for callback integrity

  • Clang/LLVMplugin: module rewriting

    • Annotation propagation saves effort by inferring annotations of module functions


Software fault isolation with api integrity and multi principal modules

Example: annotation propagation

//linux/drivers/net/e1000/e1000_main.c

int e1000_probe(structpci_dev *pcidev) {

….}

structpci_driver e1000_driver = {

.probe = e1000_probe

};

//from linux/include/pci_driver.h

structpci_driver {

int (*probe)(structpci_dev *pcidev)

principal(pcidev)

pre(copy(ref(structpci_dev), pcidev)

}

//linux/drivers/net/ixgbe/ixgbe_main.c

intixgbe_probe(structpci_dev *pcidev) {

….}

structpci_driverixgbe_driver = {

.probe = ixgbe_probe

};

LXFI propagates annotation on probe to modules


Software fault isolation with api integrity and multi principal modules

Evaluation

  • Security

  • Annotation effort

  • Performance overhead


Software fault isolation with api integrity and multi principal modules

Security

  • Test LXFI with three real privilege escalation exploits

  • Stopping real attacks requires API integrity


Software fault isolation with api integrity and multi principal modules

Annotation effort

  • Annotate kernel APIs for 10 modules, one at a time

  • Count:

    • # of annotated core kernel functions a module calls

    • # of function pointer declarations a module exports to core kernel


Software fault isolation with api integrity and multi principal modules

Sharing reduces annotation effort


Software fault isolation with api integrity and multi principal modules

LXFI performance

  • netperf, 1 Gigabit e1000 network card, LAN

  • Stresses LXFI

~30% decrease


Software fault isolation with api integrity and multi principal modules

CPU time of LXFI actions for netperf

  • Room for improvement

80%


Software fault isolation with api integrity and multi principal modules

Future work

  • Improve performance

    • Faster capability management such as BGI’s

  • Extend annotation language to enforce other types of API integrity

    • Perhaps based on Singularity’s contracts


Software fault isolation with api integrity and multi principal modules

Related work

  • Type-safe kernels: Singularity [MSR-TR05]

    • LXFI provides similar guarantees in C

    • Good support for revocation (transfer) and principals

  • Software fault isolation

    • LXFI extends existing SFI systems (SFI, XFI, BGI) with annotation language


Software fault isolation with api integrity and multi principal modules

Conclusion

  • Extend SFI with annotation language for:

    • Argument integrity

    • Callback integrity

    • Principals

  • LXFI: Prototype for Linux

    • Annotated 10 kernel modules

    • Prevented 3 real privilege escalation exploits

    • 2-4X CPU overhead when stressing with netperf


Software fault isolation with api integrity and multi principal modules

Q & A


  • Login