user_fixup.c 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /* user_fixup.c: Fix up user copy faults.
  2. *
  3. * Copyright (C) 2004 David S. Miller <davem@redhat.com>
  4. */
  5. #include <linux/compiler.h>
  6. #include <linux/kernel.h>
  7. #include <linux/string.h>
  8. #include <linux/errno.h>
  9. #include <asm/uaccess.h>
  10. /* Calculating the exact fault address when using
  11. * block loads and stores can be very complicated.
  12. * Instead of trying to be clever and handling all
  13. * of the cases, just fix things up simply here.
  14. */
  15. unsigned long copy_from_user_fixup(void *to, const void __user *from, unsigned long size)
  16. {
  17. char *dst = to;
  18. const char __user *src = from;
  19. while (size) {
  20. if (__get_user(*dst, src))
  21. break;
  22. dst++;
  23. src++;
  24. size--;
  25. }
  26. if (size)
  27. memset(dst, 0, size);
  28. return size;
  29. }
  30. unsigned long copy_to_user_fixup(void __user *to, const void *from, unsigned long size)
  31. {
  32. char __user *dst = to;
  33. const char *src = from;
  34. while (size) {
  35. if (__put_user(*src, dst))
  36. break;
  37. dst++;
  38. src++;
  39. size--;
  40. }
  41. return size;
  42. }
  43. unsigned long copy_in_user_fixup(void __user *to, void __user *from, unsigned long size)
  44. {
  45. char __user *dst = to;
  46. char __user *src = from;
  47. while (size) {
  48. char tmp;
  49. if (__get_user(tmp, src))
  50. break;
  51. if (__put_user(tmp, dst))
  52. break;
  53. dst++;
  54. src++;
  55. size--;
  56. }
  57. return size;
  58. }