M4U: fix security vulnerability

[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
diff --git a/drivers/misc/mediatek/m4u/mt2601/m4u.c b/drivers/misc/mediatek/m4u/mt2601/m4u.c
index 1f68ff2..e6a3518 100644
--- a/drivers/misc/mediatek/m4u/mt2601/m4u.c
+++ b/drivers/misc/mediatek/m4u/mt2601/m4u.c
@@ -292,6 +292,7 @@
 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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 				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 @@
 					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 @@
 				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);