Commit edf779ffccc836661a7b654d320571a6c220caea

Authored by bellard
1 parent 121061dc

use kernel like macros for user access (will be useful someday to have a better error checking


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@634 c046a42c-6fe2-441c-8c8c-71466251a162
linux-user/elfload.c
... ... @@ -263,19 +263,11 @@ struct exec
263 263  
264 264 #define DLINFO_ITEMS 11
265 265  
266   -#define put_user(x,ptr) (void)(*(ptr) = (typeof(*ptr))(x))
267   -#define get_user(ptr) (typeof(*ptr))(*(ptr))
268   -
269 266 static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
270 267 {
271 268 memcpy(to, from, n);
272 269 }
273 270  
274   -static inline void memcpy_tofs(void * to, const void * from, unsigned long n)
275   -{
276   - memcpy(to, from, n);
277   -}
278   -
279 271 extern unsigned long x86_stack_size;
280 272  
281 273 static int load_aout_interp(void * exptr, int interp_fd);
... ... @@ -373,11 +365,13 @@ static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
373 365 return 0; /* bullet-proofing */
374 366 }
375 367 while (argc-- > 0) {
376   - if (!(tmp1 = tmp = get_user(argv+argc))) {
  368 + tmp = argv[argc];
  369 + if (!tmp) {
377 370 fprintf(stderr, "VFS: argc is wrong");
378 371 exit(-1);
379 372 }
380   - while (get_user(tmp++));
  373 + tmp1 = tmp;
  374 + while (*tmp++);
381 375 len = tmp - tmp1;
382 376 if (p < len) { /* this shouldn't happen - 128kB */
383 377 return 0;
... ... @@ -395,7 +389,7 @@ static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
395 389 }
396 390 }
397 391 if (len == 0 || offset == 0) {
398   - *(pag + offset) = get_user(tmp);
  392 + *(pag + offset) = *tmp;
399 393 }
400 394 else {
401 395 int bytes_to_copy = (len > offset) ? offset : len;
... ... @@ -599,7 +593,8 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc,
599 593 {
600 594 target_ulong *argv, *envp;
601 595 target_ulong *sp, *csp;
602   -
  596 + int v;
  597 +
603 598 /*
604 599 * Force 16 byte _final_ alignment here for generality.
605 600 */
... ... @@ -616,8 +611,8 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc,
616 611 sp -= ((unsigned long)csp & 15UL) / sizeof(*sp);
617 612  
618 613 #define NEW_AUX_ENT(nr, id, val) \
619   - put_user (tswapl(id), sp + (nr * 2)); \
620   - put_user (tswapl(val), sp + (nr * 2 + 1))
  614 + put_user (id, sp + (nr * 2)); \
  615 + put_user (val, sp + (nr * 2 + 1))
621 616 sp -= 2;
622 617 NEW_AUX_ENT (0, AT_NULL, 0);
623 618  
... ... @@ -647,20 +642,26 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc,
647 642 sp -= argc+1;
648 643 argv = sp;
649 644 if (!ibcs) {
650   - put_user(tswapl((target_ulong)envp),--sp);
651   - put_user(tswapl((target_ulong)argv),--sp);
  645 + put_user((target_ulong)envp,--sp);
  646 + put_user((target_ulong)argv,--sp);
652 647 }
653   - put_user(tswapl(argc),--sp);
  648 + put_user(argc,--sp);
654 649 info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff);
655 650 while (argc-->0) {
656   - put_user(tswapl((target_ulong)p),argv++);
657   - while (get_user(p++)) /* nothing */ ;
  651 + put_user((target_ulong)p,argv++);
  652 + do {
  653 + get_user(v, p);
  654 + p++;
  655 + } while (v != 0);
658 656 }
659 657 put_user(0,argv);
660 658 info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff);
661 659 while (envc-->0) {
662   - put_user(tswapl((target_ulong)p),envp++);
663   - while (get_user(p++)) /* nothing */ ;
  660 + put_user((target_ulong)p,envp++);
  661 + do {
  662 + get_user(v, p);
  663 + p++;
  664 + } while (v != 0);
664 665 }
665 666 put_user(0,envp);
666 667 info->env_end = (unsigned int)((unsigned long)p & 0xffffffff);
... ...
linux-user/qemu.h
... ... @@ -4,6 +4,7 @@
4 4 #include "thunk.h"
5 5  
6 6 #include <signal.h>
  7 +#include <string.h>
7 8 #include "syscall_defs.h"
8 9  
9 10 #include "cpu.h"
... ... @@ -120,4 +121,121 @@ long target_mremap(unsigned long old_addr, unsigned long old_size,
120 121 unsigned long new_addr);
121 122 int target_msync(unsigned long start, unsigned long len, int flags);
122 123  
  124 +/* user access */
  125 +
  126 +#define VERIFY_READ 0
  127 +#define VERIFY_WRITE 1
  128 +
  129 +#define access_ok(type,addr,size) (1)
  130 +
  131 +#define __put_user(x,ptr)\
  132 +({\
  133 + int size = sizeof(*ptr);\
  134 + switch(size) {\
  135 + case 1:\
  136 + stb(ptr, (typeof(*ptr))(x));\
  137 + break;\
  138 + case 2:\
  139 + stw(ptr, (typeof(*ptr))(x));\
  140 + break;\
  141 + case 4:\
  142 + stl(ptr, (typeof(*ptr))(x));\
  143 + break;\
  144 + case 8:\
  145 + stq(ptr, (typeof(*ptr))(x));\
  146 + break;\
  147 + default:\
  148 + abort();\
  149 + }\
  150 + 0;\
  151 +})
  152 +
  153 +#define __get_user(x, ptr) \
  154 +({\
  155 + int size = sizeof(*ptr);\
  156 + switch(size) {\
  157 + case 1:\
  158 + x = (typeof(*ptr))ldub(ptr);\
  159 + break;\
  160 + case 2:\
  161 + x = (typeof(*ptr))lduw(ptr);\
  162 + break;\
  163 + case 4:\
  164 + x = (typeof(*ptr))ldl(ptr);\
  165 + break;\
  166 + case 8:\
  167 + x = (typeof(*ptr))ldq(ptr);\
  168 + break;\
  169 + default:\
  170 + abort();\
  171 + }\
  172 + 0;\
  173 +})
  174 +
  175 +static inline unsigned long __copy_to_user(void *dst, const void *src,
  176 + unsigned long size)
  177 +{
  178 + memcpy(dst, src, size);
  179 + return 0;
  180 +}
  181 +
  182 +static inline unsigned long __copy_from_user(void *dst, const void *src,
  183 + unsigned long size)
  184 +{
  185 + memcpy(dst, src, size);
  186 + return 0;
  187 +}
  188 +
  189 +static inline unsigned long __clear_user(void *dst, unsigned long size)
  190 +{
  191 + memset(dst, 0, size);
  192 + return 0;
  193 +}
  194 +
  195 +#define put_user(x,ptr)\
  196 +({\
  197 + int __ret;\
  198 + if (access_ok(VERIFY_WRITE, ptr, sizeof(*ptr)))\
  199 + __ret = __put_user(x, ptr);\
  200 + else\
  201 + __ret = -EFAULT;\
  202 + __ret;\
  203 +})
  204 +
  205 +#define get_user(x,ptr)\
  206 +({\
  207 + int __ret;\
  208 + if (access_ok(VERIFY_READ, ptr, sizeof(*ptr)))\
  209 + __ret = __get_user(x, ptr);\
  210 + else\
  211 + __ret = -EFAULT;\
  212 + __ret;\
  213 +})
  214 +
  215 +static inline unsigned long copy_to_user(void *dst, const void *src,
  216 + unsigned long size)
  217 +{
  218 + if (access_ok(VERIFY_WRITE, dst, size))
  219 + return __copy_to_user(dst, src, size);
  220 + else
  221 + return size;
  222 +}
  223 +
  224 +static inline unsigned long copy_from_user(void *dst, const void *src,
  225 + unsigned long size)
  226 +{
  227 + if (access_ok(VERIFY_READ, src, size))
  228 + return __copy_from_user(dst, src, size);
  229 + else
  230 + return size;
  231 +}
  232 +
  233 +static inline unsigned long clear_user(void *dst, unsigned long size)
  234 +{
  235 + if (access_ok(VERIFY_WRITE, dst, size))
  236 + return __clear_user(dst, size);
  237 + else
  238 + return size;
  239 +}
  240 +
123 241 #endif
... ...
linux-user/signal.c
... ... @@ -450,69 +450,6 @@ int do_sigaction(int sig, const struct target_sigaction *act,
450 450 return 0;
451 451 }
452 452  
453   -#define __put_user(x,ptr)\
454   -({\
455   - int size = sizeof(*ptr);\
456   - switch(size) {\
457   - case 1:\
458   - stb(ptr, (typeof(*ptr))(x));\
459   - break;\
460   - case 2:\
461   - stw(ptr, (typeof(*ptr))(x));\
462   - break;\
463   - case 4:\
464   - stl(ptr, (typeof(*ptr))(x));\
465   - break;\
466   - case 8:\
467   - stq(ptr, (typeof(*ptr))(x));\
468   - break;\
469   - default:\
470   - abort();\
471   - }\
472   - 0;\
473   -})
474   -
475   -#define __get_user(x, ptr) \
476   -({\
477   - int size = sizeof(*ptr);\
478   - switch(size) {\
479   - case 1:\
480   - x = (typeof(*ptr))ldub(ptr);\
481   - break;\
482   - case 2:\
483   - x = (typeof(*ptr))lduw(ptr);\
484   - break;\
485   - case 4:\
486   - x = (typeof(*ptr))ldl(ptr);\
487   - break;\
488   - case 8:\
489   - x = (typeof(*ptr))ldq(ptr);\
490   - break;\
491   - default:\
492   - abort();\
493   - }\
494   - 0;\
495   -})
496   -
497   -
498   -#define __copy_to_user(dst, src, size)\
499   -({\
500   - memcpy(dst, src, size);\
501   - 0;\
502   -})
503   -
504   -#define __copy_from_user(dst, src, size)\
505   -({\
506   - memcpy(dst, src, size);\
507   - 0;\
508   -})
509   -
510   -#define __clear_user(dst, size)\
511   -({\
512   - memset(dst, 0, size);\
513   - 0;\
514   -})
515   -
516 453 #ifndef offsetof
517 454 #define offsetof(type, field) ((size_t) &((type *)0)->field)
518 455 #endif
... ... @@ -707,10 +644,8 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
707 644  
708 645 frame = get_sigframe(ka, env, sizeof(*frame));
709 646  
710   -#if 0
711 647 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
712 648 goto give_sigsegv;
713   -#endif
714 649 err |= __put_user((/*current->exec_domain
715 650 && current->exec_domain->signal_invmap
716 651 && sig < 32
... ... @@ -773,10 +708,8 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
773 708  
774 709 frame = get_sigframe(ka, env, sizeof(*frame));
775 710  
776   -#if 0
777 711 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
778 712 goto give_sigsegv;
779   -#endif
780 713  
781 714 err |= __put_user((/*current->exec_domain
782 715 && current->exec_domain->signal_invmap
... ... @@ -1172,10 +1105,9 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
1172 1105 struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame));
1173 1106 int err = 0;
1174 1107  
1175   -#if 0
1176 1108 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
1177   - return 1;
1178   -#endif
  1109 + return /* 1 */;
  1110 +
1179 1111 __put_user_error(&frame->info, (target_ulong *)&frame->pinfo, err);
1180 1112 __put_user_error(&frame->uc, (target_ulong *)&frame->puc, err);
1181 1113 err |= copy_siginfo_to_user(&frame->info, info);
... ...
linux-user/syscall.c
... ... @@ -239,27 +239,6 @@ extern int setresgid(gid_t, gid_t, gid_t);
239 239 extern int getresgid(gid_t *, gid_t *, gid_t *);
240 240 extern int setgroups(int, gid_t *);
241 241  
242   -#define put_user(x,ptr)\
243   -({\
244   - int size = sizeof(*ptr);\
245   - switch(size) {\
246   - case 1:\
247   - stb(ptr, (typeof(*ptr))(x));\
248   - break;\
249   - case 2:\
250   - stw(ptr, (typeof(*ptr))(x));\
251   - break;\
252   - case 4:\
253   - stl(ptr, (typeof(*ptr))(x));\
254   - break;\
255   - case 8:\
256   - stq(ptr, (typeof(*ptr))(x));\
257   - break;\
258   - default:\
259   - abort();\
260   - }\
261   - 0;\
262   -})
263 242 static inline long get_errno(long ret)
264 243 {
265 244 if (ret == -1)
... ...