• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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