uaccess_user.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
  3. * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
  4. * Licensed under the GPL
  5. */
  6. #include <string.h>
  7. #include "user_util.h"
  8. #include "uml_uaccess.h"
  9. #include "task.h"
  10. #include "kern_util.h"
  11. #include "os.h"
  12. #include "longjmp.h"
  13. int __do_copy_from_user(void *to, const void *from, int n,
  14. void **fault_addr, void **fault_catcher)
  15. {
  16. struct tt_regs save = TASK_REGS(get_current())->tt;
  17. unsigned long fault;
  18. int faulted;
  19. fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
  20. __do_copy, &faulted);
  21. TASK_REGS(get_current())->tt = save;
  22. if(!faulted)
  23. return 0;
  24. else if (fault)
  25. return n - (fault - (unsigned long) from);
  26. else
  27. /* In case of a general protection fault, we don't have the
  28. * fault address, so NULL is used instead. Pretend we didn't
  29. * copy anything. */
  30. return n;
  31. }
  32. static void __do_strncpy(void *dst, const void *src, int count)
  33. {
  34. strncpy(dst, src, count);
  35. }
  36. int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
  37. void **fault_addr, void **fault_catcher)
  38. {
  39. struct tt_regs save = TASK_REGS(get_current())->tt;
  40. unsigned long fault;
  41. int faulted;
  42. fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
  43. __do_strncpy, &faulted);
  44. TASK_REGS(get_current())->tt = save;
  45. if(!faulted) return(strlen(dst));
  46. else return(-1);
  47. }
  48. static void __do_clear(void *to, const void *from, int n)
  49. {
  50. memset(to, 0, n);
  51. }
  52. int __do_clear_user(void *mem, unsigned long len,
  53. void **fault_addr, void **fault_catcher)
  54. {
  55. struct tt_regs save = TASK_REGS(get_current())->tt;
  56. unsigned long fault;
  57. int faulted;
  58. fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
  59. __do_clear, &faulted);
  60. TASK_REGS(get_current())->tt = save;
  61. if(!faulted) return(0);
  62. else return(len - (fault - (unsigned long) mem));
  63. }
  64. int __do_strnlen_user(const char *str, unsigned long n,
  65. void **fault_addr, void **fault_catcher)
  66. {
  67. struct tt_regs save = TASK_REGS(get_current())->tt;
  68. int ret;
  69. unsigned long *faddrp = (unsigned long *)fault_addr;
  70. jmp_buf jbuf;
  71. *fault_catcher = &jbuf;
  72. if(UML_SETJMP(&jbuf) == 0)
  73. ret = strlen(str) + 1;
  74. else ret = *faddrp - (unsigned long) str;
  75. *fault_addr = NULL;
  76. *fault_catcher = NULL;
  77. TASK_REGS(get_current())->tt = save;
  78. return ret;
  79. }
  80. /*
  81. * Overrides for Emacs so that we follow Linus's tabbing style.
  82. * Emacs will notice this stuff at the end of the file and automatically
  83. * adjust the settings for this buffer only. This must remain at the end
  84. * of the file.
  85. * ---------------------------------------------------------------------------
  86. * Local variables:
  87. * c-file-style: "linux"
  88. * End:
  89. */