diff --git a/src/system/kernel/arch/x86/arch_x86.S b/src/system/kernel/arch/x86/arch_x86.S index 58e20fc8cc..f731299222 100644 --- a/src/system/kernel/arch/x86/arch_x86.S +++ b/src/system/kernel/arch/x86/arch_x86.S @@ -276,19 +276,32 @@ FUNCTION(arch_cpu_user_strlcpy): /* Copy at most count - 1 bytes */ dec %ecx - /* move data by bytes */ + /* If count is now 0, skip straight to null terminating + as our loop will otherwise overflow */ + cmp $0,%ecx + jne .L_user_strlcpy_copy_begin + movb $0,(%edi) + jmp .L_user_strlcpy_source_count + +.L_user_strlcpy_copy_begin: cld - repnz +.L_user_strlcpy_copy_loop: + /* move data by bytes */ movsb + cmpb $0,-1(%esi) + je .L_user_strlcpy_copy_loop_done + loop .L_user_strlcpy_copy_loop - /* null terminate string */ - movb $0,(%edi) - dec %esi - +.L_user_strlcpy_copy_loop_done: /* check if we copied the entire source string */ cmp $0,%ecx jne .L_user_strlcpy_source_done +.L_user_strlcpy_zero_terminate: + /* null terminate string */ + movb $0,(%edi) + dec %esi + /* count remaining bytes in src */ .L_user_strlcpy_source_count: not %ecx @@ -297,11 +310,9 @@ FUNCTION(arch_cpu_user_strlcpy): scasb .L_user_strlcpy_source_done: - movl %esi,%eax subl 20(%esp),%eax subl $1,%eax - /* restore the old fault handler */ movl %ebx,(%edx)