diff options
author | David Chu <david.chu@mediatek.com> | 2017-03-01 01:07:47 -0800 |
---|---|---|
committer | David Chu <david.chu@mediatek.com> | 2017-03-01 07:56:56 -0800 |
commit | c490aca77cb2b1fca54191f7feb34ab45490ead7 (patch) | |
tree | 88d0cf69a7c91d8faef71b82b6a341d26cba3a44 | |
parent | 6c9c195c0a040d1f5c92b36dcc6026f7d176e6e8 (diff) | |
download | mediatek-android-mediatek-pike-3.10-nougat-mr1-wear-release.tar.gz |
M4U: fix security vulnerabilityandroid-wear-7.1.1_r0.16android-mediatek-pike-3.10-nougat-mr1-wear-release
[Detail] no check portID when use copyfromuser
[Solution] check port ID in m4u ioctl when use copyfromuser
CVE-2017-0500 CVE-2017-0501 CVE-2017-0502
Change-Id: I4896b08e483c0738e31d12b542c77d93dfec8ecd
-rw-r--r-- | drivers/misc/mediatek/m4u/mt2601/m4u.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/drivers/misc/mediatek/m4u/mt2601/m4u.c b/drivers/misc/mediatek/m4u/mt2601/m4u.c index 1f68ff2857ea..e6a351837380 100644 --- a/drivers/misc/mediatek/m4u/mt2601/m4u.c +++ b/drivers/misc/mediatek/m4u/mt2601/m4u.c @@ -292,6 +292,7 @@ struct timer_list perf_timer; static M4U_MODULE_ID_ENUM m4u_port_2_module(const M4U_PORT_ID_ENUM portID) { M4U_MODULE_ID_ENUM moduleID = M4U_CLNTMOD_UNKNOWN; + switch (portID) { case M4U_PORT_MDP_RDMA: @@ -610,6 +611,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_T_POWER_ON, copy_from_user failed, %d\n", ret); return -EFAULT; } + if (ModuleID < 0 || ModuleID >= M4U_CLNTMOD_UNKNOWN) { + M4UMSG("from user module id is invald,%d\n", ModuleID); + return -EFAULT; + } ret = m4u_power_on(); break; @@ -621,6 +626,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_T_POWER_OFF, copy_from_user failed, %d\n", ret); return -EFAULT; } + if (ModuleID < 0 || ModuleID >= M4U_CLNTMOD_UNKNOWN) { + M4UMSG("from user module id is invald,%d\n", ModuleID); + return -EFAULT; + } ret = m4u_power_off(); break; @@ -632,6 +641,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_T_ALLOC_MVA, copy_from_user failed: %d\n", ret); return -EFAULT; } + if (m4u_module.eModuleID < 0 || m4u_module.eModuleID >= M4U_CLNTMOD_UNKNOWN) { + M4UMSG("from user module id is invald,%d\n", m4u_module.eModuleID); + return -EFAULT; + } if (m4u_module.MVAStart == -1) /* work around for wrap layer */ { @@ -679,6 +692,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_T_QUERY_MVA, copy_from_user failed: %d\n", ret); return -EFAULT; } + if (m4u_module.eModuleID < 0 || m4u_module.eModuleID >= M4U_CLNTMOD_UNKNOWN) { + M4UMSG("from user module id is invald,%d\n", m4u_module.eModuleID); + return -EFAULT; + } M4ULOG("-MTK_M4U_T_QUERY_MVA, module_id=%d, BufAddr=0x%x, BufSize=%d \r\n", m4u_module.eModuleID, m4u_module.BufAddr, m4u_module.BufSize); @@ -705,6 +722,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_T_DEALLOC_MVA, copy_from_user failed: %d\n", ret); return -EFAULT; } + if (m4u_module.eModuleID < 0 || m4u_module.eModuleID >= M4U_CLNTMOD_UNKNOWN) { + M4UMSG("from user module id is invald,%d\n", m4u_module.eModuleID); + return -EFAULT; + } M4ULOG("MTK_M4U_T_DEALLOC_MVA, eModuleID:%d, VABuf:0x%x, Length:%d, MVAStart=0x%x \r\n", m4u_module.eModuleID, m4u_module.BufAddr, m4u_module.BufSize, m4u_module.MVAStart); @@ -750,6 +771,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_Manual_Insert_Entry, copy_from_user failed: %d\n", ret); return -EFAULT; } + if (m4u_module.eModuleID < 0 || m4u_module.eModuleID >= M4U_CLNTMOD_UNKNOWN) { + M4UMSG("from user module id is invald,%d\n", m4u_module.eModuleID); + return -EFAULT; + } M4ULOG(" ManualInsertTLBEntry, eModuleID:%d, Entry_MVA:0x%x, locked:%d\r\n", m4u_module.eModuleID, m4u_module.EntryMVA, m4u_module.Lock); @@ -767,6 +792,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR("m4u_insert_seq_range , copy_from_user failed: %d\n", ret); return -EFAULT; } + if (m4u_module.eModuleID < 0 || m4u_module.eModuleID >= M4U_CLNTMOD_UNKNOWN) { + M4UMSG("from user module id is invald,%d\n", m4u_module.eModuleID); + return -EFAULT; + } ret = m4u_insert_seq_range(m4u_module.eModuleID, m4u_module.MVAStart, @@ -782,6 +811,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_Invalid_TLB_Range, copy_from_user failed: %d\n", ret); return -EFAULT; } + if (m4u_module.eModuleID < 0 || m4u_module.eModuleID >= M4U_CLNTMOD_UNKNOWN) { + M4UMSG("from user module id is invald,%d\n", m4u_module.eModuleID); + return -EFAULT; + } M4ULOG("MTK_M4U_Invalid_TLB_Range(), eModuleID:%d, MVAStart=0x%x, MVAEnd=0x%x\n", m4u_module.eModuleID, m4u_module.MVAStart, m4u_module.MVAEnd); @@ -798,6 +831,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_Invalid_TLB_Range, copy_from_user failed, %d\n", ret); return -EFAULT; } + if (ModuleID < 0 || ModuleID >= M4U_CLNTMOD_UNKNOWN) { + M4UMSG("from user module id is invald,%d\n", ModuleID); + return -EFAULT; + } /* ret = m4u_invalid_tlb_all(); */ break; @@ -809,6 +846,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_Invalid_TLB_Range, copy_from_user failed, %d\n", ret); return -EFAULT; } + if (ModuleID < 0 || ModuleID >= M4U_CLNTMOD_UNKNOWN) { + M4UMSG("from user module id is invald,%d\n", ModuleID); + return -EFAULT; + } m4u_dump_main_tlb_tags(); ret = m4u_dump_reg(); @@ -822,6 +863,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_Invalid_TLB_Range, copy_from_user failed, %d\n", ret); return -EFAULT; } + if (ModuleID < 0 || ModuleID >= M4U_CLNTMOD_UNKNOWN) { + M4UMSG("from user module id is invald,%d\n", ModuleID); + return -EFAULT; + } ret = m4u_dump_info(); m4u_dump_pagetable(ModuleID); @@ -835,6 +880,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_T_CACHE_INVALID_AFTER_HW_WRITE_MEM, copy_from_user failed: %d\n", ret); return -EFAULT; } + if (m4u_cache_data.eModuleID < 0 || m4u_cache_data.eModuleID >= M4U_CLNTMOD_UNKNOWN) { + M4UMSG("from user module id is invald,%d\n", m4u_cache_data.eModuleID); + return -EFAULT; + } M4ULOG("MTK_M4U_T_CACHE_INVALID_AFTER_HW_WRITE_MEM(), moduleID=%d, eCacheSync=%d, buf_addr=0x%x, buf_length=0x%x\n", m4u_cache_data.eModuleID, m4u_cache_data.eCacheSync, m4u_cache_data.BufAddr, m4u_cache_data.BufSize); @@ -865,6 +914,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_T_CONFIG_PORT, copy_from_user failed: %d\n", ret); return -EFAULT; } + if (m4u_port.ePortID < 0 || m4u_port.ePortID >= M4U_PORT_NUM) { + M4UMSG("from user port id is invald,%d\n", m4u_port.ePortID); + return -EFAULT; + } M4ULOG("ePortID=%d, Virtuality=%d, Security=%d, Distance=%d, Direction=%d\n", m4u_port.ePortID, m4u_port.Virtuality, m4u_port.Security, m4u_port.Distance, m4u_port.Direction); @@ -879,6 +932,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_T_CONFIG_PORT_ROTATOR, copy_from_user failed: %d\n", ret); return -EFAULT; } + if (m4u_port_rotator.ePortID < 0 || m4u_port_rotator.ePortID >= M4U_PORT_NUM) { + M4UMSG("from user port id is invald,%d\n", m4u_port_rotator.ePortID); + return -EFAULT; + } ret = m4u_config_port_rotator(&m4u_port_rotator); break; @@ -894,6 +951,14 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_T_INSERT_WRAP_RANGE, copy_from_user failed: %d\n", ret); return -EFAULT; } + if (m4u_wrap_range.ePortID < 0 || m4u_wrap_range.ePortID >= M4U_PORT_NUM) { + M4UMSG("from user port id is invald,%d\n", m4u_wrap_range.ePortID); + return -EFAULT; + } + if (m4u_wrap_range.eModuleID < 0 || m4u_wrap_range.eModuleID >= M4U_CLNTMOD_UNKNOWN) { + M4UMSG("from user module id is invald,%d\n", m4u_wrap_range.eModuleID); + return -EFAULT; + } M4ULOG("PortID=%d, eModuleID=%d, MVAStart=0x%x, MVAEnd=0x%x\n", m4u_wrap_range.ePortID, m4u_wrap_range.eModuleID, @@ -914,6 +979,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_T_MONITOR_START, copy_from_user failed, %d\n", ret); return -EFAULT; } + if (PortID < 0 || PortID >= M4U_PORT_NUM) { + M4UMSG("from user port id is invald,%d\n", PortID); + return -EFAULT; + } ret = m4u_monitor_start(); break; @@ -926,6 +995,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_T_MONITOR_STOP, copy_from_user failed, %d\n", ret); return -EFAULT; } + if (PortID < 0 || PortID >= M4U_PORT_NUM) { + M4UMSG("from user port id is invald,%d\n", PortID); + return -EFAULT; + } ret = m4u_monitor_stop(); break; @@ -937,6 +1010,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_T_RESET_MVA_RELEASE_TLB, copy_from_user failed: %d\n", ret); return -EFAULT; } + if (ModuleID < 0 || ModuleID >= M4U_CLNTMOD_UNKNOWN) { + M4UMSG("from user module id is invald,%d\n", ModuleID); + return -EFAULT; + } ret = m4u_reset_mva_release_tlb(ModuleID); break; @@ -965,6 +1042,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_T_ALLOC_MVA, copy_from_user failed: %d\n", ret); return -EFAULT; } + if (m4u_module.eModuleID < 0 || m4u_module.eModuleID >= M4U_CLNTMOD_UNKNOWN) { + M4UMSG("from user module id is invald,%d\n", m4u_module.eModuleID); + return -EFAULT; + } mva = m4u_module.MVAStart; va = m4u_module.BufAddr; size = m4u_module.BufSize; @@ -1013,6 +1094,10 @@ static long MTK_M4U_ioctl(struct file *a_pstFile, M4UERR(" MTK_M4U_T_ALLOC_MVA, copy_from_user failed: %d\n", ret); return -EFAULT; } + if (m4u_module.eModuleID < 0 || m4u_module.eModuleID >= M4U_CLNTMOD_UNKNOWN) { + M4UMSG("from user module id is invald,%d\n", m4u_module.eModuleID); + return -EFAULT; + } M4ULOG("-MTK_M4U_T_REGISTER_BUF, module_id=%d, BufAddr=0x%x, BufSize=%d \r\n", m4u_module.eModuleID, m4u_module.BufAddr, m4u_module.BufSize); |