閱讀498 返回首頁    go 阿裏雲 go 技術社區[雲棲]


安卓O內核的加固

236762_6i9mpat4yla0zw1.jpg


安卓用戶空間的加固使得越來越多攻擊者開始研究linux內核,這使得去年發現的安卓安全的漏洞,1/3都在內核上。在安卓8.0(Oreo)中,程序員們做出了巨大的努力來加固內核,以減少安全漏洞。

Android Nougat通過把內核和用戶進程隔離開來,使用SELinux ioctl進行過濾,並請求seccomp-bpf的支持(能夠在處理不受信任的輸入時,過濾對係統調用的訪問),以保護內核。安卓8.0重點關注內核上的保護,其中主要有4個安全加固特征,並在第一個發行版發布時,將之以補丁的形式發布所有支持的設備上。

加固用戶複製功能

用戶的複製功能原理是將用戶空間的數據傳輸到內核中,然後再返回到用戶空間中。從2014年開始,缺少或是不合理的邊界檢查已經導致了45%的安卓內核漏洞。加固的用戶複製功能添加了邊界檢查,它可以幫助開發者定位誤用並修複他們代碼中的bug。當然,如果出現隱蔽的驅動bug,這些功能的加固使得這樣的bug難以被利用。

這些特征在linux內核4.8版本中有介紹,我們將這些補丁打到了安卓的linux 3.18版本的內核上了。

int buggy_driver_function(void __user *src, size_t size)
{
   /* potential size_t overflow (don’t do this) */
   u8 *buf = kmalloc(size * N, GPF_KERNEL);
   …
   /* results in buf smaller than size, and a heap overflow */
   if (copy_from_user(buf, src, size))
   return -EFAULT;


   /* never reached with CONFIG_HARDENED_USERCOPY=y */
}

上述是加固後的用戶複製功能預防漏洞的一個例子。

Privileged Access Never(PAN)仿真

加固的用戶複製功能能夠幫助我們找到並防禦安全問題,也能在開發者使用它們的時候起到作用。目前,所有的內核代碼,包括驅動,都能直接訪問用戶空間的內存,這會導致各種各樣的安全問題。

為了防禦這個瓿,CPU供應商介紹了一些諸如
x86平台上的Supervisor Mode Access Prevention (SMAP),ARM v8.1上的Privileged Access Never (PAN)。這些特征可以預防內核直接訪問用戶空間,並確保開發者訪問它通過用戶複製功能。不幸的是,這些特征還並沒有在設備上得到廣泛應用。

Linux的Upstream介紹一種使用軟件模擬PAN在ARM版的4.3內核和ARM64版的4.10內核上的應用的方法。

使用加固的用戶空間,PAN模擬能幫助我們在Pixel手機上的4個內核驅動上,找到並修複漏洞。
int buggy_driver_copy_data(struct mydata *src, void __user *ptr){   /* failure to keep track of user space pointers */   struct mydata *dst = (struct mydata *)ptr;   …   /* read/write from/to an arbitrary user space memory location */   dst->field = … ;    /* use copy_(from|to)_user instead! */   …   /* never reached with PAN (emulation) or SMAP */}

以上是PAN模擬防禦安全漏洞的一個例子。

內核地址空間布局隨機化(KASLR)

安卓使用了內核地址空間布局隨機化這個技術已經好幾年了。隨機化的內存布局使得代碼重用攻擊不再一定起作用,也就使得攻擊者尤其是遠程攻擊者更難進行利用。安卓8.0把這個特征帶到了內核。Linux從3.14版本開始已經支持x86平台上的KASLR,ARM64平台上的KASLR也已經從4.6版本開始支持。安卓8.0使得KASLR在安卓內核4.4上和更新的版本開始受到支持。

KASLR通過在每次啟動時隨機化內核代碼的地址來防禦內核漏洞。例如,在ARM64平台上,它根據設備的內存配置,添加了13-25位的熵,這會使得代碼重用攻擊更加困難。

初始化時確定隻讀內存

最終的加固特征繼承了內核已有的內存保護,這種保護機製通過在內核初始化後,創建標記為隻讀的內存區域。這使得開發者在初始化階段,當數據需要可寫權限時有可能改善保護機製,但在那之後不能再進行修改。使得可寫的內存變得更少可以減少來自內核的攻擊,使得漏洞利用更加困難。

在初始化時確定的隻讀內存在內核4.6中有介紹,我們把它移植到了安卓3.18內核以及更新的版本上。當我們應用這些保護機製到內核的一些數據結構上時,這一特征對於那些工作在內核驅動的開發崗位上的開發者非常有用。

總結

安卓O包含了防禦內核上的大多數的安全漏洞機製。這非常重要,因為安卓上85%的內核安全漏洞來自於驅動供應商,並且缺少詳細的代碼審查。這些更新使得驅動開發者在開發時更容易發現公共的漏洞,並在它們到達用戶設備之前阻止它。

最後更新:2017-09-14 19:02:31

  上一篇:go  Go語言與數據庫開發:01-05
  下一篇:go  BCG與阿裏研究院等聯合揭秘中國互聯網經濟:成功的關鍵是什麼?