arc: add z_arch_user_string_nlen
Safely measure the length of a potentially dubious string. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
3cef6deb16
commit
b1dec2992e
2 changed files with 79 additions and 6 deletions
|
@ -18,6 +18,15 @@
|
|||
#include <kernel.h>
|
||||
#include <kernel_structs.h>
|
||||
#include <misc/printk.h>
|
||||
#include <exc_handle.h>
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
Z_EXC_DECLARE(z_arch_user_string_nlen);
|
||||
|
||||
static const struct z_exc_handle exceptions[] = {
|
||||
Z_EXC_HANDLE(z_arch_user_string_nlen)
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* @brief Fault handler
|
||||
|
@ -26,15 +35,25 @@
|
|||
* and is responsible only for reporting the error. Once reported, it then
|
||||
* invokes the user provided routine _SysFatalErrorHandler() which is
|
||||
* responsible for implementing the error handling policy.
|
||||
*
|
||||
* @return This function does not return.
|
||||
*/
|
||||
void _Fault(const NANO_ESF *esf)
|
||||
void _Fault(NANO_ESF *esf)
|
||||
{
|
||||
u32_t vector, code, parameter;
|
||||
u32_t exc_addr = _arc_v2_aux_reg_read(_ARC_V2_EFA);
|
||||
u32_t ecr = _arc_v2_aux_reg_read(_ARC_V2_ECR);
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
for (int i = 0; i < ARRAY_SIZE(exceptions); i++) {
|
||||
u32_t start = (u32_t)exceptions[i].start;
|
||||
u32_t end = (u32_t)exceptions[i].end;
|
||||
|
||||
if (esf->pc >= start && esf->pc < end) {
|
||||
esf->pc = (u32_t)(exceptions[i].fixup);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
vector = _ARC_V2_ECR_VECTOR(ecr);
|
||||
code = _ARC_V2_ECR_CODE(ecr);
|
||||
parameter = _ARC_V2_ECR_PARAMETER(ecr);
|
||||
|
|
|
@ -47,9 +47,10 @@
|
|||
GTEXT(_arc_userspace_enter)
|
||||
GTEXT(_arc_do_syscall)
|
||||
GTEXT(_user_thread_entry_wrapper)
|
||||
|
||||
|
||||
|
||||
GTEXT(z_arch_user_string_nlen)
|
||||
GTEXT(z_arch_user_string_nlen_fault_start)
|
||||
GTEXT(z_arch_user_string_nlen_fault_end)
|
||||
GTEXT(z_arch_user_string_nlen_fixup)
|
||||
/*
|
||||
* @brief Wrapper for _thread_entry in the case of user thread
|
||||
*
|
||||
|
@ -211,3 +212,56 @@ SECTION_FUNC(TEXT, _arc_do_syscall)
|
|||
mov r6, 0
|
||||
|
||||
rtie
|
||||
|
||||
|
||||
/*
|
||||
* size_t z_arch_user_string_nlen(const char *s, size_t maxsize, int *err_arg)
|
||||
*/
|
||||
SECTION_FUNC(TEXT, z_arch_user_string_nlen)
|
||||
/* int err; */
|
||||
sub_s sp,sp,0x4
|
||||
|
||||
/* Initial error value (-1 failure), store at [sp,0] */
|
||||
mov_s r3, -1
|
||||
st_s r3, [sp, 0]
|
||||
|
||||
/* Loop setup.
|
||||
* r12 (position locator) = s - 1
|
||||
* r0 (length counter return value)) = 0
|
||||
* lp_count = maxsize + 1
|
||||
* */
|
||||
sub r12, r0, 0x1
|
||||
mov_s r0, 0
|
||||
add_s r1, r1, 1
|
||||
mov lp_count, r1
|
||||
|
||||
strlen_loop:
|
||||
z_arch_user_string_nlen_fault_start:
|
||||
/* is the byte at ++r12 a NULL? if so, we're done. Might fault! */
|
||||
ldb.aw r1, [r12, 1]
|
||||
|
||||
z_arch_user_string_nlen_fault_end:
|
||||
brne_s r1, 0, not_null
|
||||
|
||||
strlen_done:
|
||||
/* Success, set err to 0 */
|
||||
mov_s r1, 0
|
||||
st_s r1, [sp, 0]
|
||||
|
||||
z_arch_user_string_nlen_fixup:
|
||||
/* *err_arg = err; Pop stack and return */
|
||||
ld_s r1, [sp, 0]
|
||||
add_s sp, sp, 4
|
||||
j_s.d [blink]
|
||||
st_s r1, [r2, 0]
|
||||
|
||||
not_null:
|
||||
/* check if we've hit the maximum, if so we're done. */
|
||||
brne.d.nt lp_count, 0x1, inc_len
|
||||
sub lp_count, lp_count, 0x1
|
||||
b_s strlen_done
|
||||
|
||||
inc_len:
|
||||
/* increment length measurement, loop again */
|
||||
add_s r0, r0, 1
|
||||
b_s strlen_loop
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue