Group of Software Security In Progress

GoSSIP @ LoCCS.Shanghai Jiao Tong University

TypeSan: Practical Type Confusion Detection

由Vrije Universiteit Amsterdam(阿姆斯特丹自由大学)和普渡大学的人一起完成。

论文下载 CCS’16

Introduction

Typecasting在C++中被用于将一个指针对象从一个类型转换为另一个类型。但是由于C++并不强制保护类型安全以及内存安全,不安全的typecasting就会引起type confusion漏洞

  • 例如,将一个父类实例强转为一个子类类型,但是由于在父类类型的定义缺少一些子类中的成员以及虚函数声明,一旦程序随后要使用子类中的这些成员的数据或者是要调用相应的虚函数,那么程序就会将父类实例中位于同一偏移量的内存上的无关数据,当做子类类型中相关成员或者是虚函数指针进行使用。
  • CVE-2015-3077: https://googleprojectzero.blogspot.jp/2015/07/one-perfect-bug-exploiting-type_20.html

在Typecasting中,可以分为两类:upcast以及downcast。

  • upcast:将一个子类实例转化为祖先类,这一过程是安全的,子类实例中会包含所有父类的域
  • downcast:将一个父类实例转化为子孙类

because the data layout is such that an object from a derived class contains the fields of its parent classes at the same relative offsets from each other.

关于C++类继承的内存布局(单继承、多继承、虚拟继承): http://www.cnblogs.com/chio/archive/2007/11/25/971644.html

C++允许相应的upcast以及downcast,并且允许程序员指定在运行过程中是否要检查downcast的正确性。

  • C++提供了三种基本的cast函数:reinterpret_cast, dynamic_cast以及static_cast
  • 其中dynamic_cast在运行时会强制进行类型检查,因此这个函数是安全的,但是会带来昂贵的overhead开销
  • static_cast以及reinterpret_cast没有运行时类型检查来保证转换的安全性。

针对type confusion的防护可以分为两类:一种基于对象实例中虚表指针,另一种基于disjoint metadata。

System Design

本文提出了针对Type confusion的防护,在提高type-confusion检测覆盖率的同时,也降低了防护所带来的overhead。

Fig

  • instrumentation layer: 在代码编译时插入hooks来监视objects的分配,以及潜在的不安全的cast
  • type management service:编码类型信息,进行typecast的认证
  • metadata storage service:存储了pointer-to-type mapping,用于在typecast认证过程中查询object的类型信息。

runtime overhead由以下两部分组成:

  • overhead for maintaining metadata (allocating and deallocating objects)
  • overhead for explicit type checks at cast locations

本文通过新定义的两个Service来简化这两个过程的复杂度,达到缩减overhead的目的。

Instrumentation Layer

  • TypeSan在LLVM的编译过程中添加了一个pass来检测object的分配,在object分配时添加一个指令来存储相应的pointer-to-type mapping。
  • 同时当遇到一个downcast操作时,TypeSan就会插入一个调用,进行typecasting verification。

Type Management Service

  • 在针对不安全的typecast的安全检测可以分为两步,首先根据目标对象,获取对象在内存分配时的类型,根据目标对象的初始类型来检测所要转换的目标类型是否合法。

所以这个serive维持了两个表:

  • Type layout table:Type layout tables describe each relevant offset within an allocation to enable fast lookups of the offset-specific type information during a check
  • Type relationship table:用来保存每一种类型可以转换的类型。

所以在检测过程中,系统会首先根据对象的type layout来从Type layout table中确定目标对象的类型,再根据相应的Type relationship table中进行typecast的认证。

Metadata Storage Service

这个sevice是用于根据对象的基地址来查询相应的type layout table中的信息。

关键的影响因素有两点:(i) fast update operations,(ii) range-based lookups

考虑到在内存同一页面,对齐策略是一样的,可以保证每一个alignment-sized slot对应一个单独的对象。 所以作者给出了一个page table-like infrastructure,在常数时间内根据对象地址查找到相应的元信息。

Fig

Evaluation

在实验阶段,作者利用了SPEC CPU2006 C++ benchmarks以及Firefox的Octane, SunSpider, Dromaeo benchmarks。

首先通过一些自己写的microbenchmarks,检测了TypeSan在allocation-time以及typecast-time时造成的额外开销,并与CaVer进行了比较,借以说明TypeSan在记录object信息以及进行verification的时间开销是常数级别的。

Fig

Fig

接下来针对SPEC以及Firefox,检测了TypeSan的Performance overhead以及Memory usage:

Fig

最后检测了检测覆盖率,依旧是和CaVer比较,检测包括了Object Allocation的识别率以及Typecast的识别率:

Fig