11---
22title : Arm®v8-M Security Extensions <br /> Requirements on Development Tools
3- version : 1.3
4- date-of-issue : 04 August 2023
3+ version : 1.4
4+ date-of-issue : 05 April 2024
55set-quote-highlight : true
66# LaTeX specific variables
7- copyright-text :
Copyright 2019, 2021-2023 Arm Limited and/or its affiliates <[email protected] >. 8- draftversion : false
7+ copyright-text :
Copyright 2019, 2021-2024 Arm Limited and/or its affiliates <[email protected] >. 8+ draftversion : true
99# Jekyll specific variables
1010header_counter : true
1111toc : true
@@ -155,6 +155,13 @@ Copyright 2019, 2021-2023 Arm Limited and/or its affiliates <open-source-office@
155155 [ Non-secure function pointers] ( #non-secure-function-pointer ) .
156156* Fixed typos.
157157
158+ #### Changes for next release
159+
160+ * Added [ Requirement #47 ] ( #requirement-47 ) to address a security issue in the
161+ handling of arguments to CMSE Entry functions.
162+ * Added [ Requirement #58 ] ( #requirement-58 ) to address a security issue in the
163+ handling of return values from CMSE Non-secure calls.
164+
158165## References
159166
160167This document refers to the following documents.
@@ -1138,9 +1145,51 @@ caller stack frame](#figure5).
11381145
11391146
11401147
1141- ### Return from an entry function
1148+ Calls from Non-secure state follow the [[AAPCS]](#AAPCS), which states that the
1149+ caller is responsible for zero- or sign-extending arguments of integral
1150+ Fundamental Data Types smaller than a word to 4 bytes. An Entry function must
1151+ not assume that callers follow this rule, that is, it cannot presume that
1152+ integral parameters will have been zero- or sign-extended to 4 bytes. For
1153+ example, an attacker might create code that passes arguments out of their
1154+ declared type's range in an attempt to cause out-of-bounds memory accesses.
11421155
11431156<span id="requirement-47" class="requirement-box"></span>
1157+ > A compiler generating code for an entry function must, for each parameter
1158+ > that is an integral Fundamental Data Type smaller than a word, make no
1159+ > assumptions about the value of the padding bits, even when the value of
1160+ > those bits are defined by the AAPCS.
1161+
1162+ A possible implementation is shown below:
1163+
1164+ ```c
1165+ int array[256];
1166+
1167+ __attribute__((cmse_nonsecure_entry))
1168+ int func(unsigned char idx) {
1169+ return array[idx];
1170+ }
1171+ ```
1172+
1173+ ``` c
1174+ __acle_se_func:
1175+ func:
1176+ ...
1177+ @ narrow ' idx' to 8 bits before first use
1178+ uxtb r0, r0
1179+ movw r1, :lower16:array
1180+ movt r1, :upper16:array
1181+ ldr.w r0, [r1, r0, lsl #2 ]
1182+ ...
1183+ bxns lr
1184+ ```
1185+
1186+ We recommend that function parameters with integral types smaller than 4
1187+ bytes should be avoided. This recommendation extends to underlying types of
1188+ ` enum ` used as parameters.
1189+
1190+ ### Return from an entry function
1191+
1192+ <span id =" requirement-48 " class =" requirement-box " ></span >
11441193
11451194> An entry function must use the BXNS instruction to return to its
11461195> non-secure caller.
@@ -1153,7 +1202,7 @@ To prevent information leakage when an entry function returns, you must clear th
11531202registers that contain secret information
11541203([ Information leakage] ( #information-leakage ) ).
11551204
1156- <span id="requirement-48 " class="requirement-box"></span>
1205+ <span id =" requirement-49 " class =" requirement-box " ></span >
11571206
11581207> The code sequence directly preceding the ` BXNS ` instruction that transitions
11591208> to non-secure code must:
@@ -1186,7 +1235,7 @@ difficult.
11861235An entry function can be called from secure or non-secure state. Software needs
11871236to distinguish between these cases.
11881237
1189- <span id="requirement-49 " class="requirement-box"></span>
1238+ <span id =" requirement-50 " class =" requirement-box " ></span >
11901239
11911240> The following intrinsic function must be provided if bit 1 of macro
11921241> ` __ARM_FEATURE_CMSE ` is set:
@@ -1212,12 +1261,12 @@ only happen via function pointers. This is a consequence of separating
12121261secure and non-secure code into separate executable files as described
12131262in [ Executable files] ( #executable-files ) .
12141263
1215- <span id="requirement-50 " class="requirement-box"></span>
1264+ <span id =" requirement-51 " class =" requirement-box " ></span >
12161265
12171266> A non-secure function type must be declared using the function attribute
12181267> ` __attribute__((cmse_nonsecure_call)) ` .
12191268
1220- <span id="requirement-51 " class="requirement-box"></span>
1269+ <span id =" requirement-52 " class =" requirement-box " ></span >
12211270
12221271> A non-secure function type must only be used as a base type of a pointer.
12231272
@@ -1226,7 +1275,7 @@ executable file only contains secure function definitions.
12261275
12271276### Performing a call
12281277
1229- <span id="requirement-52 " class="requirement-box"></span>
1278+ <span id =" requirement-53 " class =" requirement-box " ></span >
12301279
12311280> A function call through a pointer with a non-secure function type as its
12321281> base type must switch to the non-secure state.
@@ -1245,7 +1294,7 @@ that contain values that are used after the non-secure function call
12451294must be restored after the call returns. Secure code cannot depend on
12461295the non-secure state to restore these registers.
12471296
1248- <span id="requirement-53 " class="requirement-box"></span>
1297+ <span id =" requirement-54 " class =" requirement-box " ></span >
12491298
12501299> The code sequence directly preceding the ` BLXNS ` instruction that
12511300> transitions to non-secure code must:
@@ -1263,7 +1312,7 @@ the non-secure state to restore these registers.
12631312A toolchain could provide you with the means to specify that some
12641313types of variables never hold secret information.
12651314
1266- <span id="requirement-54 " class="requirement-box"></span>
1315+ <span id =" requirement-55 " class =" requirement-box " ></span >
12671316
12681317> When the non-secure function call returns, caller- and callee-saved
12691318> registers saved before the call must be restored. This includes bits [ 27:0]
@@ -1290,7 +1339,7 @@ usage is required according to [[AAPCS]](#AAPCS), the non-secure state expects
12901339the arguments on the non-secure stack and writes the return value to non-secure
12911340memory.
12921341
1293- <span id="requirement-55 " class="requirement-box"></span>
1342+ <span id =" requirement-56 " class =" requirement-box " ></span >
12941343
12951344> To avoid using the non-secure stack, a toolchain may constrain the
12961345> following, for a non-secure function type:
@@ -1299,7 +1348,7 @@ memory.
12991348> * The type of each parameter.
13001349> * The return type.
13011350
1302- <span id="requirement-56 " class="requirement-box"></span>
1351+ <span id =" requirement-57 " class =" requirement-box " ></span >
13031352
13041353> A compiler compiling a call to a non-secure function must do either of the
13051354> following:
@@ -1335,6 +1384,51 @@ The stack usage during a non-secure function call is shown in figure
13351384
13361385![ <span id =" figure6 " class =" citation-label " >** Caller's stack frame of a non-secure function call** </span >] ( stack-frame-non-secure.svg )
13371386
1387+ The return of values from Non-secure function calls follows the
1388+ [[ AAPCS]] ( #AAPCS ) , which states that the callee is responsible for zero- or
1389+ sign-extending return values of integral Fundamental Data Types smaller than a
1390+ word to 4 bytes. A Secure function must not assume that Non-secure callees
1391+ follow this rule, that is, it cannot presume that integral returned values will
1392+ have been zero- or sign-extended to 4 bytes. For example, an attacker might
1393+ create code that returns values out of their declared type's range in an
1394+ attempt to cause out-of-bounds memory accesses.
1395+
1396+ <span id =" requirement-58 " class =" requirement-box " ></span >
1397+ > A compiler generating code for a Non-secure function call must, for each
1398+ > returned value that is an integral Fundamental Data Type smaller than a word,
1399+ > make no assumptions about the value of the padding bits, even when the value
1400+ > of those bits are defined by the AAPCS.
1401+
1402+ A possible implementation is shown below:
1403+
1404+ ``` c
1405+ __attribute__ ((cmse_nonsecure_call))
1406+ unsigned short (* nonsecurefunc)(void);
1407+
1408+ void securefunc(int * array) {
1409+ unsigned short idx = nonsecurefunc();
1410+ print(array[ idx] );
1411+ }
1412+ ```
1413+
1414+ ```c
1415+ securefunc:
1416+ ...
1417+ @ r1 has the address of 'nonsecurefunc'
1418+ @ r2 has 'array'
1419+ @ non-secure function call
1420+ blxns r1
1421+ @ narrow 'idx' (returned value in r0) to a 16-bit value
1422+ uxth r0, r0
1423+ ldr.w r0, [r2, r0, lsl #2]
1424+ bl print
1425+ ...
1426+ ```
1427+
1428+ We recommend that function return values with integral types smaller than 4
1429+ bytes should be avoided. This recommendation extends to underlying types of
1430+ ` enum ` used as return values.
1431+
13381432## Non-secure function pointer
13391433
13401434A function pointer that has its LSB unset is a non-secure function
@@ -1399,7 +1493,7 @@ void call_callback(void) {
13991493This is just an optimisation technique and hence it is not required for the
14001494correct usage of non-secure function pointers.
14011495
1402- <span id="requirement-57 " class="requirement-box"></span>
1496+ <span id =" requirement-59 " class =" requirement-box " ></span >
14031497
14041498> The following intrinsics are defined if bit 1 of macro
14051499> ` __ARM_FEATURE_CMSE ` is set:
@@ -1428,12 +1522,12 @@ A non-secure callable function is a function that is expected to be placed in an
14281522NSC region. Its functionality is identical to an entry function, but instead of
14291523a secure gateway veneer the function starts with the ` SG ` instruction.
14301524
1431- <span id="requirement-58 " class="requirement-box"></span>
1525+ <span id =" requirement-60 " class =" requirement-box " ></span >
14321526
14331527> A non-secure callable function must be declared by using the attribute
14341528> ` __attribute__((cmse_nonsecure_callable)) ` on a function declaration.
14351529
1436- <span id="requirement-59 " class="requirement-box"></span>
1530+ <span id =" requirement-61 " class =" requirement-box " ></span >
14371531
14381532> A non-secure callable function is identical to an entry function except that:
14391533>
@@ -1449,7 +1543,7 @@ Toolchain support is needed to prevent inadvertent secure gateways
14491543from occurring ([ Inadverted secure
14501544gataway] ( #inadvertent-secure-gateway ) ).
14511545
1452- <span id="requirement-60 " class="requirement-box"></span>
1546+ <span id =" requirement-62 " class =" requirement-box " ></span >
14531547
14541548> A toolchain must provide a way for the programmer to guarantee that a
14551549> non-secure callable function does not contain an inadvertent ` SG ` instruction
@@ -1465,7 +1559,7 @@ non-secure state, but cannot be called by the non-secure state. An example use
14651559would be to provide tail-calls from an entry function to non-secure returning
14661560functions.
14671561
1468- <span id="requirement-61 " class="requirement-box"></span>
1562+ <span id =" requirement-63 " class =" requirement-box " ></span >
14691563
14701564> A non-secure returning function must be declared by using the attribute
14711565> ` __attribute__((cmse_nonsecure_return)) ` on a function declaration.
0 commit comments