Commit edf779ffccc836661a7b654d320571a6c220caea
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
Showing
4 changed files
with
142 additions
and
112 deletions
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) | ... | ... |