uaccess_user.c 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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 <setjmp.h>
  7. #include <string.h>
  8. #include "user_util.h"
  9. #include "uml_uaccess.h"
  10. #include "task.h"
  11. #include "kern_util.h"
  12. int __do_copy_from_user(void *to, const void *from, int n,
  13. void **fault_addr, void **fault_catcher)
  14. {
  15. struct tt_regs save = TASK_REGS(get_current())->tt;
  16. unsigned long fault;
  17. int faulted;
  18. fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
  19. __do_copy, &faulted);
  20. TASK_REGS(get_current())->tt = save;
  21. if(!faulted) return(0);
  22. else return(n - (fault - (unsigned long) from));
  23. }
  24. static void __do_strncpy(void *dst, const void *src, int count)
  25. {
  26. strncpy(dst, src, count);
  27. }
  28. int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
  29. void **fault_addr, void **fault_catcher)
  30. {
  31. struct tt_regs save = TASK_REGS(get_current())->tt;
  32. unsigned long fault;
  33. int faulted;
  34. fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
  35. __do_strncpy, &faulted);
  36. TASK_REGS(get_current())->tt = save;
  37. if(!faulted) return(strlen(dst));
  38. else return(-1);
  39. }
  40. static void __do_clear(void *to, const void *from, int n)
  41. {
  42. memset(to, 0, n);
  43. }
  44. int __do_clear_user(void *mem, unsigned long len,
  45. void **fault_addr, void **fault_catcher)
  46. {
  47. struct tt_regs save = TASK_REGS(get_current())->tt;
  48. unsigned long fault;
  49. int faulted;
  50. fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
  51. __do_clear, &faulted);
  52. TASK_REGS(get_current())->tt = save;
  53. if(!faulted) return(0);
  54. else return(len - (fault - (unsigned long) mem));
  55. }
  56. int __do_strnlen_user(const char *str, unsigned long n,
  57. void **fault_addr, void **fault_catcher)
  58. {
  59. struct tt_regs save = TASK_REGS(get_current())->tt;
  60. int ret;
  61. unsigned long *faddrp = (unsigned long *)fault_addr;
  62. sigjmp_buf jbuf;
  63. *fault_catcher = &jbuf;
  64. if(sigsetjmp(jbuf, 1) == 0)
  65. ret = strlen(str) + 1;
  66. else ret = *faddrp - (unsigned long) str;
  67. *fault_addr = NULL;
  68. *fault_catcher = NULL;
  69. TASK_REGS(get_current())->tt = save;
  70. return ret;
  71. }
  72. /*
  73. * Overrides for Emacs so that we follow Linus's tabbing style.
  74. * Emacs will notice this stuff at the end of the file and automatically
  75. * adjust the settings for this buffer only. This must remain at the end
  76. * of the file.
  77. * ---------------------------------------------------------------------------
  78. * Local variables:
  79. * c-file-style: "linux"
  80. * End:
  81. */