diff --git a/arch/arm/arm/include/arm_user_clear.h b/arch/arm/arm/include/arm_user_clear.h new file mode 100644 index 0000000000000000000000000000000000000000..d808208aab35f50bbfdc920ab83e60d73aaea144 --- /dev/null +++ b/arch/arm/arm/include/arm_user_clear.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _ARM_USER_CLEAR_H +#define _ARM_USER_CLEAR_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +size_t _arm_clear_user(void *addr, size_t bytes); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _ARM_USER_CLEAR_H */ diff --git a/arch/arm/arm/src/clear_user.S b/arch/arm/arm/src/clear_user.S new file mode 100644 index 0000000000000000000000000000000000000000..907a50418ffc3d0478db8affdec4a6cfcea25072 --- /dev/null +++ b/arch/arm/arm/src/clear_user.S @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "asm.h" + +.syntax unified +.arm + +// size_t _arm_clear_user(void *addr, size_t bytes) +FUNCTION(_arm_clear_user) + push {r0-r6, lr} + cmp r1, #0 + beq .Lclear_user_return + tst r0, #7 + beq .Lclear_user_aligned + +.Lclear_user_byte: + mov r2, #0 +0: strb r2, [r0], #1 + subs r1, r1, #1 + beq .Lclear_user_return + tst r0, #7 + bne 0b + +.Lclear_user_aligned: + eor r3, r3 + eor r4, r4 + bics r2, r1, #15 + bne .Lclear_user_16bytes + bics r2, r1, #7 + bne .Lclear_user_8bytes + b .Lclear_user_remaining + +.Lclear_user_16bytes: + eor r5, r5 + eor r6, r6 +1: stmia r0!, {r3, r4, r5, r6} + subs r2, r2, #16 + bne 1b + ands r1, r1, #15 + beq .Lclear_user_return + bics r2, r1, #7 + beq .Lclear_user_remaining + +.Lclear_user_8bytes: +2: stmia r0!, {r3, r4} + ands r1, r1, #7 + beq .Lclear_user_return + +.Lclear_user_remaining: + mov r2, #0 +3: strb r2, [r0], #1 + subs r1, r1, #1 + bne 3b + +.Lclear_user_return: + pop {r0-r6, lr} + mov r0, #0 + bx lr + +.Lclear_user_err: + pop {r0, r1} + sub r0, r2, r0 + sub r0, r1, r0 + pop {r2-r6, lr} + bx lr + +.pushsection __exc_table, "a" + .long 0b, .Lclear_user_err + .long 1b, .Lclear_user_err + .long 2b, .Lclear_user_err + .long 3b, .Lclear_user_err +.popsection diff --git a/arch/arm/arm/src/user_copy.c b/arch/arm/arm/src/user_copy.c index f4ecd91c3c19609612ea3a50094a29359f67d3a0..081bc413c8f75dc8bab1c05752a9ce7c163c93fb 100644 --- a/arch/arm/arm/src/user_copy.c +++ b/arch/arm/arm/src/user_copy.c @@ -31,6 +31,7 @@ #include "user_copy.h" #include "arm_user_copy.h" +#include "arm_user_clear.h" #include "securec.h" #include "los_memory.h" #include "los_vm_map.h" @@ -96,15 +97,9 @@ INT32 LOS_UserMemClear(unsigned char *buf, UINT32 len) if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, len)) { (VOID)memset_s(buf, len, 0, len); } else { - unsigned char *tmp = (unsigned char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, len); - if (tmp == NULL) { - return -ENOMEM; + if (_arm_clear_user(buf, len)) { + return -EFAULT; } - (VOID)memset_s(tmp, len, 0, len); - if (_arm_user_copy(buf, tmp, len) != 0) { - ret = -EFAULT; - } - LOS_MemFree(OS_SYS_MEM_ADDR, tmp); } return ret; } diff --git a/kernel/extended/dynload/src/los_load_elf.c b/kernel/extended/dynload/src/los_load_elf.c index ef7411ebe74058b20de5226e172aefe7fdc0e3a6..a6133eb4fe5e1e7aaa0f5c339f5020f1e96400a1 100644 --- a/kernel/extended/dynload/src/los_load_elf.c +++ b/kernel/extended/dynload/src/los_load_elf.c @@ -416,42 +416,20 @@ INT32 OsGetKernelVaddr(const LosVmSpace *space, VADDR_T vaddr, VADDR_T *kvaddr) STATIC INT32 OsSetBss(const LD_ELF_PHDR *elfPhdr, INT32 fd, UINTPTR bssStart, UINT32 bssEnd, UINT32 elfProt) { - UINTPTR bssPageStart, bssStartPageAlign, bssEndPageAlign; + UINTPTR bssStartPageAlign, bssEndPageAlign; UINTPTR mapBase; - UINT32 offset, size; UINT32 bssMapSize; INT32 stackFlags; INT32 ret; - vaddr_t kvaddr = 0; - bssPageStart = ROUNDDOWN(bssStart, PAGE_SIZE); bssStartPageAlign = ROUNDUP(bssStart, PAGE_SIZE); bssEndPageAlign = ROUNDUP(bssEnd, PAGE_SIZE); - ret = LOS_UnMMap(bssPageStart, (bssEndPageAlign - bssPageStart)); - if ((ret != LOS_OK) && (bssPageStart != 0)) { - PRINT_ERR("%s[%d], Failed to unmap a region, vaddr: %#x!\n", __FUNCTION__, __LINE__, bssPageStart); - } - ret = LOS_UserSpaceVmAlloc(OsCurrProcessGet()->vmSpace, PAGE_SIZE, (VOID **)&bssPageStart, - 0, OsCvtProtFlagsToRegionFlags(elfProt, MAP_FIXED)); - if (ret != LOS_OK) { - PRINT_ERR("%s[%d], Failed to do vmm alloc!\n", __FUNCTION__, __LINE__); - return -ENOMEM; - } - ret = OsGetKernelVaddr(OsCurrProcessGet()->vmSpace, bssPageStart, &kvaddr); - if (ret != LOS_OK) { - PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__); + ret = LOS_UserMemClear((VOID *)bssStart, PAGE_SIZE - ROUNDOFFSET(bssStart, PAGE_SIZE)); + if (ret != 0) { + PRINT_ERR("%s[%d], Failed to clear bss\n", __FUNCTION__, __LINE__); return -EFAULT; } - (VOID)memset_s((VOID *)(UINTPTR)kvaddr, PAGE_SIZE, 0, PAGE_SIZE); - - offset = ROUNDDOWN(elfPhdr->offset + elfPhdr->fileSize, PAGE_SIZE); - size = ROUNDOFFSET(elfPhdr->offset + elfPhdr->fileSize, PAGE_SIZE); - ret = OsReadELFInfo(fd, (UINT8 *)(UINTPTR)kvaddr, size, offset); - if (ret != LOS_OK) { - PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__); - return -EIO; - } bssMapSize = bssEndPageAlign - bssStartPageAlign; if (bssMapSize > 0) {