Illegal access caused by an empty list. This problem is not repaired, I only test it in Nexus4 and Nexus5 with the security patch level 20161005. It will cause kernel panic.
static ssize_t msm_bus_dbg_update_request_write(struct file *file,
const char __user *ubuf, size_t cnt, loff_t *ppos)
{
...
list_for_each_entry(cldata, &cl_list, list) {
if (strstr(chid, cldata->pdata->name)) {
cldata = cldata;
strsep(&chid, " ");
if (chid) {
ret = strict_strtoul(chid, 10, &index);
if (ret) {
MSM_BUS_DBG("Index conversion"
" failed\n");
return -EFAULT;
}
} else
MSM_BUS_DBG("Error parsing input. Index not"
" found\n");
break;
}
}
msm_bus_dbg_update_request(cldata, index);
kfree(buf);
return cnt;
}
LISTHEAD(cllist);
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
if cl_list don't have any node, prev and next is point to itself;
listforeach_entry func:
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
in this func, &pos->member == (head);
now, see cldata struct:
struct msm_bus_cldata *cldata;
struct msm_bus_cldata {
const struct msm_bus_scale_pdata *pdata;
int index;
uint32_t clid;
int size;
struct dentry *file;
struct list_head list; // offset 0x14
char buffer[MAX_BUFF_SIZE];
};
pos = list_entry((head)->next, typeof(*pos), member);
cldata = &head - 0x14 = &cl_list - 0x14;
in msmbusdbgupdaterequest func:
static int msm_bus_dbg_update_request(struct msm_bus_cldata *cldata, int index)
{
int ret = 0;
if ((index < 0) || (index > cldata->pdata->num_usecases)) {
MSM_BUS_DBG("Invalid index!\n");
return -EINVAL;
}
ret = msm_bus_scale_client_update_request(cldata->clid, index);
return ret;
}
when access cldata->pdata->num_usecases, and cldata->pdata point to unknow address, it will cause kernel panic.
also, cl_list address is exports in nexus 5,
the cl_list address = 0xC1064F44,
so cldata = 0xC1064F44 - 0x14 = 0xC1064F30,
but cldata->pdata = [0xC1064F30] = 0,
so cldata->pdata->num_usecases will access address 0x4.
last_kmsg:
[ 58.790209] Unable to handle kernel NULL pointer dereference at virtual address 00000004
[ 58.790683] pgd = ea458000
[ 58.791290] [00000004] *pgd=32ab7831, *pte=00000000, *ppte=00000000
[ 58.792167] Internal error: Oops: 17 [#1] PREEMPT SMP ARM
[ 58.792585] CPU: 0 Not tainted (3.4.0-gd59db4e #1)
[ 58.792844] PC is at msm_bus_dbg_update_request_write+0x164/0x22c
[ 58.793256] LR is at msm_bus_dbg_update_request_write+0xf0/0x22c
[ 58.793491] pc : [<c01811c8>] lr : [<c0181154>] psr: 60000013
[ 58.793505] sp : ea771f08 ip : 00000034 fp : ea771f3c
[ 58.794106] r10: c10d1278 r9 : ea770000 r8 : eb67ce40
[ 58.794511] r7 : 00000011 r6 : eb67ce40 r5 : c1065004 r4 : c1064ff0
[ 58.794742] r3 : 00000000 r2 : 00000061 r1 : 00000000 r0 : 00000000
[ 58.795152] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
[ 58.795556] Control: 10c5787d Table: 3285806a DAC: 00000015
[ 58.795782]
[ 58.795789] PC: 0xc0181148:
[ 58.796376] 1148 e1a00006 e5931008 eb09c65c e3500000 0afffff5 e24b0028 e59f10fc eb09c5cb
[ 58.798445] 1168 e51b0028 e3500000 0a000009 e3a0100a e24b202c eb09e506 e3500000 0a00000b
[ 58.800668] 1188 e1da3ab2 e3130004 1a000023 e3e0000d eaffffd1 e1da3bba e3130004 0a000003
[ 58.802891] 11a8 e59f10b8 e59f20b8 e59f00b8 eb0a1872 e51b102c e3510000 ba000003 e5943000
[ 58.804974] 11c8 e5933004 e1510003 da000006 e1da3db2 e3130004 1a00000b e1a00008 eb037a79
[ 58.807237] 11e8 e1a00007 eaffffbc e5940008 ebffec38 eafffff8 e59f0070 e59f1064 eb225d0c
[ 58.809497] 1208 e3e0000b eaffffb4 e59f1060 e59f2060 e59f0060 eb0a1858 eaffffee e59f0058
[ 58.811567] 1228 e59f1058 e59f2038 eb0a1853 e3e0000d eaffffa9 e3a03004 e28a0078 e58d3000
[ 58.813651]
...
[ 58.957523]
[ 58.957530] R10: 0xc10d11f8:
[ 58.957944] 11f8 00000090 00000000 c0d0eb0c c0b07c58 c0d0eb1c c0d0eb90 00000098 00000000
[ 58.960189] 1218 c0d0eb0c c0b07c58 c0d0eb1c c0d0eb6c 000000ad 00000000 c0d0eb0c c0b07c70
[ 58.962412] 1238 c0d0eb1c c0d0ebe0 000000cb 00000000 c0d0eb0c c0b07c8c c0d0eb1c c0d0ebc4
[ 58.964503] 1258 00000043 00000000 c0d0eb0c c0b07c8c c0d0eb1c c0d0ebc4 0000004a 00000000
[ 58.966752] 1278 c0d0f328 c0b07ca8 c0d0f334 c0d0f564 000000b0 00000000 c0d0f328 c0b07cbc
[ 58.969009] 1298 c0d0f334 c0d0f53c 000000c1 00000000 c0d0f328 c0b07cd0 c0d0f334 c0d0f51c
[ 58.971269] 12b8 000000d2 00000000 c0d0f328 c0b07ce4 c0d0f334 c0d0f4fc 000000e2 00000000
[ 58.973357] 12d8 c0d0f328 c0b07cf8 c0d0f334 c0d0f44c 000000f2 00000000 c0d0f328 c0b07d0c
[ 58.975435] Process fuzz (pid: 3242, stack limit = 0xea7702f0)
[ 58.975846] Stack: (0xea771f08 to 0xea772000)
[ 58.976081] 1f00: ea2ef800 eb299548 00000000 eb67ce40 eb299540 00000011
[ 58.976503] 1f20: 000263eb ea771f78 00000011 00000000 ea771f6c ea771f40 c0264608 c0181070
[ 58.976745] 1f40: c026e744 c025f294 ea771f94 00000000 00000000 eb299540 000263eb 00000011
[ 58.977164] 1f60: ea771fa4 ea771f70 c0264774 c0264564 0002d4a4 00000000 00000000 00000000
[ 58.977581] 1f80: c0107544 0002d4a4 00000004 0000881d 00000004 c0107544 00000000 ea771fa8
[ 58.977999] 1fa0: c0107300 c0264738 0002d4a4 00000004 00000004 000263eb 00000011 00000000
[ 58.978238] 1fc0: 0002d4a4 00000004 0000881d 00000004 000080f4 00000000 00000000 be9fea9c
[ 58.978651] 1fe0: 0002bec8 be9fea40 000089ef 0000e654 20000010 00000004 00000000 00000000
[ 58.979111] [<c01811c8>] (msm_bus_dbg_update_request_write+0x164/0x22c) from [<c0264608>] (vfs_write+0xb0/0x154)
[ 58.979565] [<c0264608>] (vfs_write+0xb0/0x154) from [<c0264774>] (sys_write+0x48/0x80)
[ 58.979835] [<c0264774>] (sys_write+0x48/0x80) from [<c0107300>] (ret_fast_syscall+0x0/0x30)
[ 58.980261] Code: e51b102c e3510000 ba000003 e5943000 (e5933004)
[ 58.983832] ---[ end trace 114cfb12a6c4858a ]---
[ 58.985413] Kernel panic - not syncing: Fatal exception
[ 59.985839] Rebooting in 5 seconds..
[ 64.987517] Going down for restart now
[ 64.988789] Calling SCM to disable SPMI PMIC arbiter
没有评论:
发表评论