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,19 +263,11 @@ struct exec
263 263
264 #define DLINFO_ITEMS 11 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 static inline void memcpy_fromfs(void * to, const void * from, unsigned long n) 266 static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
270 { 267 {
271 memcpy(to, from, n); 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 extern unsigned long x86_stack_size; 271 extern unsigned long x86_stack_size;
280 272
281 static int load_aout_interp(void * exptr, int interp_fd); 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,11 +365,13 @@ static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
373 return 0; /* bullet-proofing */ 365 return 0; /* bullet-proofing */
374 } 366 }
375 while (argc-- > 0) { 367 while (argc-- > 0) {
376 - if (!(tmp1 = tmp = get_user(argv+argc))) { 368 + tmp = argv[argc];
  369 + if (!tmp) {
377 fprintf(stderr, "VFS: argc is wrong"); 370 fprintf(stderr, "VFS: argc is wrong");
378 exit(-1); 371 exit(-1);
379 } 372 }
380 - while (get_user(tmp++)); 373 + tmp1 = tmp;
  374 + while (*tmp++);
381 len = tmp - tmp1; 375 len = tmp - tmp1;
382 if (p < len) { /* this shouldn't happen - 128kB */ 376 if (p < len) { /* this shouldn't happen - 128kB */
383 return 0; 377 return 0;
@@ -395,7 +389,7 @@ static unsigned long copy_strings(int argc,char ** argv,unsigned long *page, @@ -395,7 +389,7 @@ static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
395 } 389 }
396 } 390 }
397 if (len == 0 || offset == 0) { 391 if (len == 0 || offset == 0) {
398 - *(pag + offset) = get_user(tmp); 392 + *(pag + offset) = *tmp;
399 } 393 }
400 else { 394 else {
401 int bytes_to_copy = (len > offset) ? offset : len; 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,7 +593,8 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc,
599 { 593 {
600 target_ulong *argv, *envp; 594 target_ulong *argv, *envp;
601 target_ulong *sp, *csp; 595 target_ulong *sp, *csp;
602 - 596 + int v;
  597 +
603 /* 598 /*
604 * Force 16 byte _final_ alignment here for generality. 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,8 +611,8 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc,
616 sp -= ((unsigned long)csp & 15UL) / sizeof(*sp); 611 sp -= ((unsigned long)csp & 15UL) / sizeof(*sp);
617 612
618 #define NEW_AUX_ENT(nr, id, val) \ 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 sp -= 2; 616 sp -= 2;
622 NEW_AUX_ENT (0, AT_NULL, 0); 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,20 +642,26 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc,
647 sp -= argc+1; 642 sp -= argc+1;
648 argv = sp; 643 argv = sp;
649 if (!ibcs) { 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 info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff); 649 info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff);
655 while (argc-->0) { 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 put_user(0,argv); 657 put_user(0,argv);
660 info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff); 658 info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff);
661 while (envc-->0) { 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 put_user(0,envp); 666 put_user(0,envp);
666 info->env_end = (unsigned int)((unsigned long)p & 0xffffffff); 667 info->env_end = (unsigned int)((unsigned long)p & 0xffffffff);
linux-user/qemu.h
@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
4 #include "thunk.h" 4 #include "thunk.h"
5 5
6 #include <signal.h> 6 #include <signal.h>
  7 +#include <string.h>
7 #include "syscall_defs.h" 8 #include "syscall_defs.h"
8 9
9 #include "cpu.h" 10 #include "cpu.h"
@@ -120,4 +121,121 @@ long target_mremap(unsigned long old_addr, unsigned long old_size, @@ -120,4 +121,121 @@ long target_mremap(unsigned long old_addr, unsigned long old_size,
120 unsigned long new_addr); 121 unsigned long new_addr);
121 int target_msync(unsigned long start, unsigned long len, int flags); 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 #endif 241 #endif
linux-user/signal.c
@@ -450,69 +450,6 @@ int do_sigaction(int sig, const struct target_sigaction *act, @@ -450,69 +450,6 @@ int do_sigaction(int sig, const struct target_sigaction *act,
450 return 0; 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 #ifndef offsetof 453 #ifndef offsetof
517 #define offsetof(type, field) ((size_t) &((type *)0)->field) 454 #define offsetof(type, field) ((size_t) &((type *)0)->field)
518 #endif 455 #endif
@@ -707,10 +644,8 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, @@ -707,10 +644,8 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
707 644
708 frame = get_sigframe(ka, env, sizeof(*frame)); 645 frame = get_sigframe(ka, env, sizeof(*frame));
709 646
710 -#if 0  
711 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 647 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
712 goto give_sigsegv; 648 goto give_sigsegv;
713 -#endif  
714 err |= __put_user((/*current->exec_domain 649 err |= __put_user((/*current->exec_domain
715 && current->exec_domain->signal_invmap 650 && current->exec_domain->signal_invmap
716 && sig < 32 651 && sig < 32
@@ -773,10 +708,8 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, @@ -773,10 +708,8 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
773 708
774 frame = get_sigframe(ka, env, sizeof(*frame)); 709 frame = get_sigframe(ka, env, sizeof(*frame));
775 710
776 -#if 0  
777 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 711 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
778 goto give_sigsegv; 712 goto give_sigsegv;
779 -#endif  
780 713
781 err |= __put_user((/*current->exec_domain 714 err |= __put_user((/*current->exec_domain
782 && current->exec_domain->signal_invmap 715 && current->exec_domain->signal_invmap
@@ -1172,10 +1105,9 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka, @@ -1172,10 +1105,9 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
1172 struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame)); 1105 struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame));
1173 int err = 0; 1106 int err = 0;
1174 1107
1175 -#if 0  
1176 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) 1108 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
1177 - return 1;  
1178 -#endif 1109 + return /* 1 */;
  1110 +
1179 __put_user_error(&frame->info, (target_ulong *)&frame->pinfo, err); 1111 __put_user_error(&frame->info, (target_ulong *)&frame->pinfo, err);
1180 __put_user_error(&frame->uc, (target_ulong *)&frame->puc, err); 1112 __put_user_error(&frame->uc, (target_ulong *)&frame->puc, err);
1181 err |= copy_siginfo_to_user(&frame->info, info); 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,27 +239,6 @@ extern int setresgid(gid_t, gid_t, gid_t);
239 extern int getresgid(gid_t *, gid_t *, gid_t *); 239 extern int getresgid(gid_t *, gid_t *, gid_t *);
240 extern int setgroups(int, gid_t *); 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 static inline long get_errno(long ret) 242 static inline long get_errno(long ret)
264 { 243 {
265 if (ret == -1) 244 if (ret == -1)