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,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) |