The quiter you become,the more you are able to hear!

MediaTek M4U Driver Arbitrary Memory Overwrite

Author: geneblue

Blog: https://geneblue.github.io/

环境

1
2
3
金立f103
android5.0.2
Linux version 3.10.65+ (android@BIANYI-26) (gcc version 4.9 20140514 (mtk-20150408) (GCC) ) #1 SMP PREEMPT Wed May 11 16:52:18 CST 2016

分析

1
drivers/misc/mediatek/m4u/mt6735/m4u.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
static long MTK_M4U_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
...
switch (cmd)
{
case MTK_M4U_T_CONFIG_TF:
{
M4U_TF_STRUCT rM4UTF;
ret = copy_from_user(&rM4UTF, (void *) arg, sizeof(M4U_TF_STRUCT));
if (ret)
{
M4UMSG("MTK_M4U_T_CONFIG_TF,copy_from_user failed:%d\n", ret);
return -EFAULT;
}

ret = m4u_enable_tf(rM4UTF.port, rM4UTF.fgEnable);
}
break;
...
}
...
}

int m4u_enable_tf(int port, bool fgenable)
{
gM4uPort[port].enable_tf = fgenable;
return 0;
}

MediaTek 6735 处理的驱动 /proc/m4u 的 ioctl 接口存在一个任意地址写一字节漏洞,该漏洞通过 MTK_M4U_T_CONFIG_TF 命令即可触发,主要是因为 m4u_enable_tf 函数没有对输入参数做校验。

m4u_enable_tf 对应的汇编代码如下:

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

var_5= -5
var_4= -4

SUB SP, SP, #0x10
STR W0, [SP,#0x10+var_4]
STRB W1, [SP,#0x10+var_5]
ADRP X0, #off_FFFFFFC000D9B4B8@PAGE
ADD X2, X0, #off_FFFFFFC000D9B4B8@PAGEOFF
LDRSW X1, [SP,#0x10+var_4] # X1 有符号 int 值
MOV X0, X1
UBFM X0, X0, #0x3F, #0x3E
ADD X0, X0, X1
UBFM X0, X0, #0x3C, #0x3B
ADD X0, X2, X0
LDRB W1, [SP,#0x10+var_5]
STRB W1, [X0,#0xC] # PC when crash
MOV W0, #0
ADD SP, SP, #0x10
RET

FFFFFFC000D9B4B8 + 0x30 * X0 + 0xc = W1(one byte)

ptmx_fops = 0xFFFFFFC000EB1380

覆盖 ptmx_fops 表地址,覆盖一个字节: 0xee ffffffee00eb1380 崩溃日志见 log1.txt

该任意地址覆盖只能间隔性(0x30)覆盖一个字节, 64位内核暂时找不到好的利用方式。

参考