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