diff options
Diffstat (limited to 'tags/2.6.18-12/30082a_x86-add-copy_user_handle_tail.patch')
-rw-r--r-- | tags/2.6.18-12/30082a_x86-add-copy_user_handle_tail.patch | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/tags/2.6.18-12/30082a_x86-add-copy_user_handle_tail.patch b/tags/2.6.18-12/30082a_x86-add-copy_user_handle_tail.patch new file mode 100644 index 0000000..27cfb86 --- /dev/null +++ b/tags/2.6.18-12/30082a_x86-add-copy_user_handle_tail.patch @@ -0,0 +1,56 @@ +commit 1129585a08baf58582c0da91e572cb29e3179acf +Author: Vitaly Mayatskikh <v.mayatskih@gmail.com> +Date: Wed Jul 2 15:48:21 2008 +0200 + + x86: introduce copy_user_handle_tail() routine + + Introduce generic C routine for handling necessary tail operations after + protection fault in copy_*_user on x86. + + Signed-off-by: Vitaly Mayatskikh <v.mayatskih@gmail.com> + Acked-by: Linus Torvalds <torvalds@linux-foundation.org> + Signed-off-by: Ingo Molnar <mingo@elte.hu> + +Backported to Debian's 2.6.18 by dann frazier <dannf@debian.org> + +diff -urpN linux-source-2.6.18.orig/arch/x86_64/lib/usercopy.c linux-source-2.6.18/arch/x86_64/lib/usercopy.c +--- linux-source-2.6.18.orig/arch/x86_64/lib/usercopy.c 2006-09-19 21:42:06.000000000 -0600 ++++ linux-source-2.6.18/arch/x86_64/lib/usercopy.c 2008-07-16 02:39:08.000000000 -0600 +@@ -164,3 +164,26 @@ unsigned long copy_in_user(void __user * + } + EXPORT_SYMBOL(copy_in_user); + ++/* ++ * Try to copy last bytes and clear the rest if needed. ++ * Since protection fault in copy_from/to_user is not a normal situation, ++ * it is not necessary to optimize tail handling. ++ */ ++unsigned long ++copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest) ++{ ++ char c; ++ unsigned zero_len; ++ ++ for (; len; --len) { ++ if (__get_user_nocheck(c, from++, sizeof(char))) ++ break; ++ if (__put_user_nocheck(c, to++, sizeof(char))) ++ break; ++ } ++ ++ for (c = 0, zero_len = len; zerorest && zero_len; --zero_len) ++ if (__put_user_nocheck(c, to++, sizeof(char))) ++ break; ++ return len; ++} +diff -urpN linux-source-2.6.18.orig/include/asm-x86_64/uaccess.h linux-source-2.6.18/include/asm-x86_64/uaccess.h +--- linux-source-2.6.18.orig/include/asm-x86_64/uaccess.h 2008-07-16 00:01:24.000000000 -0600 ++++ linux-source-2.6.18/include/asm-x86_64/uaccess.h 2008-07-16 02:39:15.000000000 -0600 +@@ -355,4 +355,7 @@ unsigned long __clear_user(void __user * + extern long __copy_from_user_inatomic(void *dst, const void __user *src, unsigned size); + #define __copy_to_user_inatomic copy_user_generic + ++unsigned long ++copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest); ++ + #endif /* __X86_64_UACCESS_H */ |