1#!/usr/bin/env python 2# coding:utf-8 3 4# 5# Copyright (C) 2022 Huawei Technologies Co., Ltd. 6# Licensed under the Mulan PSL v2. 7# You can use this software according to the terms and conditions of the Mulan 8# PSL v2. 9# You may obtain a copy of Mulan PSL v2 at: 10# http://license.coscl.org.cn/MulanPSL2 11# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY 12# KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 13# NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 14# See the Mulan PSL v2 for more details. 15# 16 17 18import re 19import os 20import sys 21import uuid 22 23uuid_split_sym_list = ['-'] 24spilt_sym_list = [';', '|', ','] 25unused_sym_list = ['_'] 26unique_list = [] 27map_region_sym_list = ['-', '_', ':', '.', '@', ";"] 28permission_unique_dict = {} 29cmd_unique_dict = {} 30 31 32def dyn_conf_clean(): 33 34 unique_list.clear() 35 36 37def check_csv_sym(value): 38 39 for sym in value: 40 if sym in unused_sym_list: 41 continue 42 elif sym >= 'A' and sym <= 'Z': 43 continue 44 elif sym >= 'a' and sym <= 'z': 45 continue 46 elif sym >= '0' and sym <= '9': 47 continue 48 else: 49 raise RuntimeError("has invalid sym in csv", value) 50 51 52def classify_uuid_list(dyn_key, attrib, value, origin_value): 53 54 ans = "" 55 uuid_list = value.split(',') 56 for uuid_item in uuid_list: 57 ans = "%s%s," % (ans, str(uuid.UUID(uuid_item))) 58 59 return ans[:len(ans) - 1].strip() 60 61 62def check_context_sym(old_item, attr, value): 63 64 if len(value) == 0: 65 return -1 66 67 for sym in value: 68 if sym in uuid_split_sym_list: 69 continue 70 if sym in spilt_sym_list: 71 continue 72 if sym in unused_sym_list: 73 continue 74 if sym in map_region_sym_list: 75 continue 76 if sym >= 'A' and sym <= 'Z': 77 continue 78 if sym >= 'a' and sym <= 'z': 79 continue 80 if sym >= '0' and sym <= '9': 81 continue 82 raise RuntimeError("has invalid sym in xml", \ 83 old_item + attr, value) 84 return 0 85 86 87def do_split_and_classify(old_item, attr, split_sym_index, value): 88 89 ans = "" 90 value_list = value.split(spilt_sym_list[split_sym_index]) 91 for val in value_list: 92 val = val.strip() 93 if len(val) == 0: 94 raise RuntimeError("cannot split empty region", value) 95 if split_sym_index == len(spilt_sym_list) - 1: 96 if check_context_sym(old_item, attr, val) != 0: 97 raise RuntimeError("xml attrib cannot be NULL", \ 98 old_item + attr, value) 99 ans += val + spilt_sym_list[split_sym_index] 100 else: 101 ans += do_split_and_classify(old_item, attr, split_sym_index + 1,\ 102 val) + spilt_sym_list[split_sym_index] 103 104 return ans[: len(ans) - 1] 105 106 107def check_and_classify_attr(old_item, attr, value): 108 109 if len(value) == 0: 110 raise RuntimeError("tag %s%s is NULL in xml" % (old_item, attr)) 111 112 value = do_split_and_classify(old_item, attr, 0, value) 113 114 if attr == "uuid": 115 value = classify_uuid_list(0, 0, value, 0) 116 117 return value 118 119 120def check_iomap_range(dyn_key, attrib, value, origin_value): 121 122 if len(value) == 0: 123 raise RuntimeError("you must define iomap_range") 124 125 value.replace(" ", "") 126 iomap_ranges = value.split(";") 127 for iomap in iomap_ranges: 128 addrs = iomap.split(",") 129 # check if range is start,end format 130 if len(addrs) == 0: 131 continue 132 133 if len(addrs) != 2: 134 raise RuntimeError("iomap must be start1,end1;\ 135 start2,end2....", addrs) 136 137 if '0x' not in addrs[0] or '0x' not in addrs[1]: 138 raise RuntimeError("addr must be hex like \ 139 0xF8555000", addrs[0], addrs[1]) 140 141 # check if addr is 4K aligned 142 start = int(addrs[0], 16) 143 end = int(addrs[1], 16) 144 if start > 0xffffffffffffffff or end > 0xffffffffffffffff: 145 raise RuntimeError("addr is so large", addrs[0], addrs[1]) 146 if start % 0x1000 != 0 or end % 0x1000 != 0: 147 raise RuntimeError("addr must be 4K aligned", addrs[0], addrs[1]) 148 if end <= start: 149 raise RuntimeError("iomap range start must \ 150 smaller than end ", addrs[0], addrs[1]) 151 152 return 0 153 154 155def check_thread_limit(dyn_key, attrib, value, origin_value): 156 157 if len(value) > 0: 158 thread_limit = int(value) 159 if thread_limit > 0xffffffff or thread_limit <= 0: 160 raise RuntimeError("thread_limit is invalid", thread_limit) 161 162 163def check_upgrade(dyn_key, attrib, value, origin_value): 164 if len(value) > 0: 165 if value.lower() != 'true' and value.lower() != 'false': 166 raise RuntimeError("upgrade must be true or false", value) 167 168 169def check_virt2phys(dyn_key, attrib, value, origin_value): 170 if len(value) > 0: 171 if value.lower() != 'true' and value.lower() != 'false': 172 raise RuntimeError("virt2phys must be true or false", value) 173 174 175def check_ioremap_ns(dyn_key, attrib, value, origin_value): 176 if len(value) > 0: 177 if value.lower() != 'true' and value.lower() != 'false': 178 raise RuntimeError("ioremap_ns must be true or false", value) 179 180 181def check_get_vsrootinfo(dyn_key, attrib, value, origin_value): 182 if len(value) > 0: 183 if value.lower() != 'true' and value.lower() != 'false': 184 raise RuntimeError("get_vsrootinfo must be true or false", value) 185 186 187def check_exception_mode(dyn_key, attrib, value, origin_value): 188 if value != "restart" and value != "syscrash" and value != "ddos": 189 raise RuntimeError("unknown exception mode", value) 190 191 192def check_chip_type(dyn_key, attrib, value, origin_value): 193 194 if len(value) == 0: 195 raise RuntimeError("chip_type cannot be NULL") 196 197 if not re.match(r"[A-Za-z0-9_,]*$", value): 198 raise RuntimeError("there has invalid sym in chip type", value) 199 200 chips = value.split(",") 201 for chip in chips: 202 chip_item = chip.lower().strip() 203 if len(chip_item) > 31: 204 raise RuntimeError("{} length is larger than 31".format(chip_item), chip_item) 205 206 flag = 0 207 for attr in attrib: 208 if attr != "chip_type": 209 flag = 1 210 break 211 if flag == 0: 212 raise RuntimeError("you cannot only set chip_type in item") 213 214 215def check_drv_name(value): 216 217 if len(value) > 31 or len(value) == 0: 218 raise RuntimeError("drv name should not be NULL or \ 219length larger than 31", value) 220 221 222def check_irq(dyn_key, attrib, value, origin_value): 223 224 if len(value) == 0: 225 raise RuntimeError("irq cannot be NULL") 226 227 if ';' in value or '|' in value: 228 raise RuntimeError("irq can only split by ,", value) 229 230 irq_list = value.split(',') 231 for irq in irq_list: 232 num = int(irq, 10) 233 if num < 32: 234 raise RuntimeError("irq shoule not smaller than 32", value) 235 236 237def check_map_secure_uuid(dyn_key, attrib, value, origin_value): 238 239 if len(value) != 36: 240 raise RuntimeError("uuid len is invalid", value) 241 242 flag = 0 243 for attr in attrib: 244 if attr == "region": 245 flag = 1 246 247 if flag == 0: 248 raise RuntimeError("please set region in map secure item", attrib) 249 250 251def check_map_secure_region(dyn_key, attrib, value, origin_value): 252 253 if len(value) == 0: 254 raise RuntimeError("region cannot be NULL") 255 256 flag = 0 257 for attr in attrib: 258 if attr == "uuid": 259 flag = 1 260 261 if flag == 0: 262 raise RuntimeError("please set uuid in map secure item", attrib) 263 264 check_iomap_range(dyn_key, attrib, value, origin_value) 265 266 267def check_drv_cmd_perm_info_item_permission(dyn_key, attrib, value, origin_value): 268 269 if len(value) == 0: 270 raise RuntimeError("permssion len should not be NULL") 271 272 if not re.match(r"^[0-9]*$", value): 273 raise RuntimeError("there has invalid sym in perm", value) 274 275 if int(value, 10) > 64 or int(value, 10) < 1: 276 raise RuntimeError("perm can only in range 1-64", value) 277 278 flag = 0 279 280 for attr in attrib: 281 if attr == "cmd" and len(attrib[attr]) != 0: 282 flag = 1 283 break 284 285 if flag == 0: 286 raise RuntimeError("you should set cmd while you set cmd permission") 287 check_permssion_unique(value, origin_value) 288 289 290def check_drv_cmd_perm_info_item_cmd(dyn_key, attrib, value, origin_value): 291 292 if len(dyn_key) == 0: 293 raise RuntimeError("dyn_key len should not be 0") 294 295 flag = 0 296 297 cmd = "" 298 for attr in attrib: 299 if attr == "permission" and len(attrib[attr]) != 0: 300 flag = 1 301 if attr == "cmd" and len(attrib[attr]) != 0: 302 cmd = attrib[attr] 303 if (dyn_key, attrib[attr]) in unique_list: 304 raise RuntimeError("one cmd can only set \ 305 permission once", attrib[attr]) 306 307 unique_list.append((dyn_key, cmd)) 308 309 if flag == 0: 310 raise RuntimeError("you should set permission while \ 311 you set cmd permission") 312 check_cmd_unique(value, origin_value) 313 314 315def check_mac_info_item_permission(dyn_key, attrib, value, origin_value): 316 if len(value) == 0: 317 raise RuntimeError("permssion len should not be 0") 318 319 if ',' in value or ';' in value: 320 raise RuntimeError("multi permssiom can only split by | ", value) 321 322 flag = 0 323 324 for attr in attrib: 325 if attr == "uuid" and len(attrib[attr]) != 0: 326 flag = 1 327 break 328 329 if flag == 0: 330 raise RuntimeError("you should set uuid while \ 331 you set drvcall's permission") 332 333 for perm_num in value.split("|"): 334 if int(perm_num, 10) > 64 or int(perm_num, 10) < 1: 335 raise RuntimeError("perm can only in range 1-64", value) 336 check_permssion_unique(value, origin_value) 337 338 339def check_mac_info_item_uuid(dyn_key, attrib, value, origin_value): 340 341 if len(dyn_key) == 0: 342 raise RuntimeError("dyn_key len should not be 0") 343 344 uuid_str = "" 345 for attr in attrib: 346 if attr == "uuid" and len(attrib[attr]) != 0: 347 uuid_str = attrib[attr] 348 if ',' in uuid_str: 349 raise RuntimeError("uuid in mac can only set one", uuid_str) 350 if (dyn_key, uuid_str) in unique_list: 351 raise RuntimeError("uuid can only set once in mac", uuid_str) 352 353 unique_list.append((dyn_key, uuid_str)) 354 355 356def check_permssion_unique(value, origin_value): 357 358 value_list = value.split("|") 359 origin_value_list = origin_value.split("|") 360 if len(value) == 0 or len(value_list) != len(origin_value_list): 361 RuntimeError("permssion trans by csv failed", value, origin_value) 362 363 for (i, _) in enumerate(value_list): 364 if value_list[i] in iter(permission_unique_dict) and \ 365 permission_unique_dict.get(value_list[i]) != origin_value_list[i]: 366 raise RuntimeError("different permission set same num in csv",\ 367 value, origin_value) 368 permission_unique_dict[value_list[i]] = origin_value_list[i] 369 370 371def check_cmd_unique(value, origin_value): 372 373 value_list = value.split("|") 374 origin_value_list = origin_value.split("|") 375 if len(value) == 0 or len(value_list) != len(origin_value_list): 376 RuntimeError("cmd trans by csv failed", value, origin_value) 377 378 for (i, _) in enumerate(value_list): 379 if value_list[i] in iter(cmd_unique_dict) and \ 380 cmd_unique_dict.get(value_list[i]) != origin_value_list[i]: 381 raise RuntimeError("different cmd set same num in csv", \ 382 value, origin_value) 383 cmd_unique_dict[value_list[i]] = origin_value_list[i] 384 385 386def check_perm_apply_item(dyn_key, attrib, value, origin_value): 387 if len(value) == 0: 388 raise RuntimeError("permssion len should not be 0") 389 390 flag = 0 391 392 for attr in attrib: 393 if attr == "name" and len(attrib[attr]) != 0: 394 flag = 1 395 break 396 397 if flag == 0: 398 raise RuntimeError("you should set drv's name while \ 399 you set drv's permission") 400 check_permssion_unique(value, origin_value) 401 402 403def check_ta_config_service_name(dyn_key, attrib, value, origin_value): 404 if len(value) == 0 or len(value) >= 40: 405 raise Exception("service name is invalid", value) 406 407 408def check_ta_config_stack_size(dyn_key, attrib, value, origin_value): 409 if int(value, 10) > 0xffffffff or int(value, 10) <= 0: 410 raise Exception("stack size is invalid", value) 411 412 413def check_ta_config_heap_size(dyn_key, attrib, value, origin_value): 414 if int(value, 10) > 0xffffffff or int(value, 10) <= 0: 415 raise Exception("heap size is invalid", value) 416 417 418def check_ta_config_rpmb_size(dyn_key, attrib, value, origin_value): 419 if int(value, 10) > 0xffffffff or int(value, 10) <= 0: 420 raise Exception("rpmb size is invalid", value) 421 422 423def check_ta_config_device_id(dyn_key, attrib, value, origin_value): 424 if len(value) != 64: 425 raise Exception("device_id len is invalid", value) 426 427 for sym in value: 428 if sym >= 'A' and sym <= 'Z': 429 continue 430 elif sym >= '0' and sym <= '9': 431 continue 432 else: 433 raise RuntimeError("has invalid sym in device_id", sym, value) 434 435 436check_fun_list = { 437 'drv_perm/drv_basic_info/thread_limit': check_thread_limit, 438 'drv_perm/drv_basic_info/upgrade': check_upgrade, 439 'drv_perm/drv_basic_info/virt2phys': check_virt2phys, 440 'drv_perm/drv_basic_info/get_vsrootinfo': check_get_vsrootinfo, 441 'drv_perm/drv_basic_info/exception_mode': check_exception_mode, 442 'drv_perm/drv_basic_info/ioremap_ns': check_ioremap_ns, 443 'drv_perm/drv_io_map/item/chip_type': check_chip_type, 444 'drv_perm/drv_io_map/item/iomap': check_iomap_range, 445 'drv_perm/irq/item/irq': check_irq, 446 'drv_perm/map_secure/item/chip_type': check_chip_type, 447 'drv_perm/map_secure/item/uuid': check_map_secure_uuid, 448 'drv_perm/map_secure/item/region': check_map_secure_region, 449 'drv_perm/map_nosecure/item/chip_type': check_chip_type, 450 'drv_perm/drv_cmd_perm_info/item/cmd': check_drv_cmd_perm_info_item_cmd, 451 'drv_perm/drv_cmd_perm_info/item/permission': check_drv_cmd_perm_info_item_permission, 452 'drv_perm/drv_mac_info/item/uuid': check_mac_info_item_uuid, 453 'drv_perm/drv_mac_info/item/permission': check_mac_info_item_permission, 454 'drvcall_conf/drvcall_perm_apply/item/permission': check_perm_apply_item, 455 'ConfigInfo/TA_Basic_Info/service_name/service_name': check_ta_config_service_name, 456 'ConfigInfo/TA_Basic_Info/uuid/uuid':classify_uuid_list, 457 'ConfigInfo/TA_Manifest_Info/stack_size/stack_size': check_ta_config_stack_size, 458 'ConfigInfo/TA_Manifest_Info/heap_size/heap_size': check_ta_config_heap_size, 459 'ConfigInfo/TA_Control_Info/RPMB_Info/RPMB_size/RPMB_size': check_ta_config_rpmb_size, 460 'ConfigInfo/TA_Control_Info/DEBUG_Info/DEBUG_device_id/DEBUG_device_id': check_ta_config_device_id, 461} 462 463 464def check_fun_default(dyn_key, attrib, value, origin_value): 465 return 466 467 468def dyn_perm_check(dyn_key, attrib, value, origin_value): 469 check_fun_list.get(dyn_key, check_fun_default)(dyn_key, attrib, value, origin_value) 470 471 472def check_text_ava(old_item, text): 473 474 if text is None or len(text.strip()) == 0: 475 raise Exception("text is invalied", old_item) 476 477 478ta_config_item_list = [ 479 'ConfigInfo/TA_Basic_Info/service_name/', 480 'ConfigInfo/TA_Basic_Info/uuid/', 481 'ConfigInfo/TA_Manifest_Info/instance_keep_alive/', 482 'ConfigInfo/TA_Manifest_Info/stack_size/', 483 'ConfigInfo/TA_Manifest_Info/heap_size/', 484 'ConfigInfo/TA_Manifest_Info/multi_command/', 485 'ConfigInfo/TA_Manifest_Info/multi_session/', 486 'ConfigInfo/TA_Manifest_Info/single_instance/', 487 'ConfigInfo/TA_Control_Info/RPMB_Info/RPMB_size/', 488 'ConfigInfo/TA_Control_Info/RPMB_Info/RPMB_Permission/RPMB_general/', 489 'ConfigInfo/TA_Control_Info/SE_Info/SE_open_session/', 490 'ConfigInfo/TA_Control_Info/TUI_Info/TUI_general/', 491 'ConfigInfo/TA_Control_Info/DEBUG_Info/debug_status/', 492 'ConfigInfo/TA_Control_Info/DEBUG_Info/DEBUG_device_id/'] 493 494 495def check_ta_config(old_item, text): 496 497 if old_item in ta_config_item_list: 498 check_text_ava(old_item, text) 499 500 return True 501