1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  * Copyright (c) 2020, Linaro Limited
5  */
6 
7 #include <config.h>
8 #include <string.h>
9 #include <tee_api.h>
10 #include <utee_syscalls.h>
11 #include <util.h>
12 
13 #include "tee_api_private.h"
14 
15 #define ACCESS_RW	(TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE)
16 #define ACCESS_W_ANY	(TEE_MEMORY_ACCESS_WRITE | TEE_MEMORY_ACCESS_ANY_OWNER)
17 #define ACCESS_R	TEE_MEMORY_ACCESS_READ
18 #define ACCESS_W	TEE_MEMORY_ACCESS_WRITE
19 
20 /* System API - Misc */
21 
TEE_Panic(TEE_Result panicCode)22 void TEE_Panic(TEE_Result panicCode)
23 {
24 	_utee_panic(panicCode);
25 #ifdef __COVERITY__
26 	__coverity_panic__();
27 #endif
28 }
29 
check_res(const char * msg __maybe_unused,TEE_Result res)30 static void check_res(const char *msg __maybe_unused, TEE_Result res)
31 {
32 	if (res) {
33 		DMSG("%s: error %#"PRIx32, msg, res);
34 		TEE_Panic(0);
35 	}
36 }
37 
check_access(uint32_t flags,void * buf,size_t len)38 static TEE_Result check_access(uint32_t flags, void *buf, size_t len)
39 {
40 	if (!len)
41 		return TEE_SUCCESS;
42 
43 	if (!buf)
44 		return TEE_ERROR_SECURITY;
45 
46 	if (IS_ENABLED(CFG_TA_STRICT_ANNOTATION_CHECKS))
47 		return TEE_CheckMemoryAccessRights(flags, buf, len);
48 
49 	return TEE_SUCCESS;
50 }
51 
__utee_check_outbuf_annotation(void * buf,size_t * len)52 void __utee_check_outbuf_annotation(void *buf, size_t *len)
53 {
54 	check_res("[outbuf] len",
55 		  check_access(ACCESS_RW, len, sizeof(*len)));
56 	check_res("[outbuf] buf",
57 		  check_access(ACCESS_W_ANY, buf, *len));
58 }
59 
__utee_check_gp11_outbuf_annotation(void * buf,uint32_t * len)60 void __utee_check_gp11_outbuf_annotation(void *buf, uint32_t *len)
61 {
62 	check_res("[outbuf] len",
63 		  check_access(ACCESS_RW, len, sizeof(*len)));
64 	check_res("[outbuf] buf",
65 		  check_access(ACCESS_W_ANY, buf, *len));
66 }
67 
__utee_check_instring_annotation(const char * buf)68 void __utee_check_instring_annotation(const char *buf)
69 {
70 	check_res("[instring]",
71 		  check_access(ACCESS_R, (char *)buf, strlen(buf) + 1));
72 }
73 
__utee_check_outstring_annotation(char * buf,size_t * len)74 void __utee_check_outstring_annotation(char *buf, size_t *len)
75 {
76 	check_res("[outstring] len",
77 		  check_access(ACCESS_RW, len, sizeof(*len)));
78 	check_res("[outstring] buf",
79 		  check_access(ACCESS_W_ANY, buf, *len));
80 }
81 
__utee_check_gp11_outstring_annotation(char * buf,uint32_t * len)82 void __utee_check_gp11_outstring_annotation(char *buf, uint32_t *len)
83 {
84 	check_res("[outstring] len",
85 		  check_access(ACCESS_RW, len, sizeof(*len)));
86 	check_res("[outstring] buf",
87 		  check_access(ACCESS_W_ANY, buf, *len));
88 }
89 
__utee_check_out_annotation(void * buf,const size_t len)90 void __utee_check_out_annotation(void *buf, const size_t len)
91 {
92 	check_res("[out]",
93 		  check_access(ACCESS_W, buf, len));
94 }
95 
__utee_check_attr_in_annotation(const TEE_Attribute * attr,size_t count)96 void __utee_check_attr_in_annotation(const TEE_Attribute *attr, size_t count)
97 {
98 	check_res("[in] attr",
99 		  check_access(ACCESS_R, (void *)attr, sizeof(*attr) * count));
100 }
101 
__utee_check_gp11_attr_in_annotation(const __GP11_TEE_Attribute * attr,size_t count)102 void __utee_check_gp11_attr_in_annotation(const __GP11_TEE_Attribute *attr,
103 					  size_t count)
104 
105 {
106 	check_res("[in] attr",
107 		  check_access(ACCESS_R, (void *)attr, sizeof(*attr) * count));
108 }
109 
__utee_check_inout_annotation(void * buf,const size_t len)110 void __utee_check_inout_annotation(void *buf, const size_t len)
111 {
112 	check_res("[inout]",
113 		  check_access(ACCESS_RW, buf, len));
114 }
115