aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRene Gollent <anevilyak@gmail.com>2012-07-02 14:41:31 -0400
committerRene Gollent <anevilyak@gmail.com>2012-07-02 15:07:17 -0400
commit8695be5049294c32c45ef69f8a500dd759f46079 (patch)
tree34f5ce3a31d3b2967b0abe13782441485db33c0d
parentfb8447d59586d40fc8987ede4795ebda64354839 (diff)
Fix regressions in arch_cpu_user_strlcpy().hrev44282
- repnz movsb turns out to not actually be a legal instruction, resulting in various strings being copied incorrectly, leading to random crashes in various places. Rework to use loop instead. Thanks to Alex Smith for helping review changes and offering improvements. - Minor cleanups. - Fixes #8650 properly.
-rw-r--r--src/system/kernel/arch/x86/arch_x86.S27
1 files changed, 19 insertions, 8 deletions
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)