Commit 788f5ec40d03a79ae7aa3335d7e3cfea72c502a8
1 parent
26edcf41
copy_{to,from}_user_timeval() update, by Thayne Harbaugh.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3780 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
42 additions
and
32 deletions
linux-user/syscall.c
| ... | ... | @@ -550,30 +550,34 @@ static inline abi_long host_to_target_rusage(abi_ulong target_addr, |
| 550 | 550 | return 0; |
| 551 | 551 | } |
| 552 | 552 | |
| 553 | -static inline abi_long target_to_host_timeval(struct timeval *tv, | |
| 554 | - abi_ulong target_addr) | |
| 553 | +static inline abi_long copy_from_user_timeval(struct timeval *tv, | |
| 554 | + abi_ulong target_tv_addr) | |
| 555 | 555 | { |
| 556 | 556 | struct target_timeval *target_tv; |
| 557 | 557 | |
| 558 | - if (!lock_user_struct(VERIFY_READ, target_tv, target_addr, 1)) | |
| 558 | + if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1)) | |
| 559 | 559 | return -TARGET_EFAULT; |
| 560 | - tv->tv_sec = tswapl(target_tv->tv_sec); | |
| 561 | - tv->tv_usec = tswapl(target_tv->tv_usec); | |
| 562 | - unlock_user_struct(target_tv, target_addr, 0); | |
| 560 | + | |
| 561 | + __get_user(tv->tv_sec, &target_tv->tv_sec); | |
| 562 | + __get_user(tv->tv_usec, &target_tv->tv_usec); | |
| 563 | + | |
| 564 | + unlock_user_struct(target_tv, target_tv_addr, 0); | |
| 563 | 565 | |
| 564 | 566 | return 0; |
| 565 | 567 | } |
| 566 | 568 | |
| 567 | -static inline abi_long host_to_target_timeval(abi_ulong target_addr, | |
| 568 | - const struct timeval *tv) | |
| 569 | +static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr, | |
| 570 | + const struct timeval *tv) | |
| 569 | 571 | { |
| 570 | 572 | struct target_timeval *target_tv; |
| 571 | 573 | |
| 572 | - if (!lock_user_struct(VERIFY_WRITE, target_tv, target_addr, 0)) | |
| 574 | + if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) | |
| 573 | 575 | return -TARGET_EFAULT; |
| 574 | - target_tv->tv_sec = tswapl(tv->tv_sec); | |
| 575 | - target_tv->tv_usec = tswapl(tv->tv_usec); | |
| 576 | - unlock_user_struct(target_tv, target_addr, 1); | |
| 576 | + | |
| 577 | + __put_user(tv->tv_sec, &target_tv->tv_sec); | |
| 578 | + __put_user(tv->tv_usec, &target_tv->tv_usec); | |
| 579 | + | |
| 580 | + unlock_user_struct(target_tv, target_tv_addr, 1); | |
| 577 | 581 | |
| 578 | 582 | return 0; |
| 579 | 583 | } |
| ... | ... | @@ -612,7 +616,8 @@ static abi_long do_select(int n, |
| 612 | 616 | } |
| 613 | 617 | |
| 614 | 618 | if (target_tv_addr) { |
| 615 | - target_to_host_timeval(&tv, target_tv_addr); | |
| 619 | + if (copy_from_user_timeval(&tv, target_tv_addr)) | |
| 620 | + return -TARGET_EFAULT; | |
| 616 | 621 | tv_ptr = &tv; |
| 617 | 622 | } else { |
| 618 | 623 | tv_ptr = NULL; |
| ... | ... | @@ -628,8 +633,8 @@ static abi_long do_select(int n, |
| 628 | 633 | if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n)) |
| 629 | 634 | return -TARGET_EFAULT; |
| 630 | 635 | |
| 631 | - if (target_tv_addr) | |
| 632 | - host_to_target_timeval(target_tv_addr, &tv); | |
| 636 | + if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv)) | |
| 637 | + return -TARGET_EFAULT; | |
| 633 | 638 | } |
| 634 | 639 | |
| 635 | 640 | return ret; |
| ... | ... | @@ -3390,9 +3395,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, |
| 3390 | 3395 | { |
| 3391 | 3396 | struct timeval *tvp, tv[2]; |
| 3392 | 3397 | if (arg2) { |
| 3393 | - target_to_host_timeval(&tv[0], arg2); | |
| 3394 | - target_to_host_timeval(&tv[1], | |
| 3395 | - arg2 + sizeof (struct target_timeval)); | |
| 3398 | + if (copy_from_user_timeval(&tv[0], arg2) | |
| 3399 | + || copy_from_user_timeval(&tv[1], | |
| 3400 | + arg2 + sizeof(struct target_timeval))) | |
| 3401 | + goto efault; | |
| 3396 | 3402 | tvp = tv; |
| 3397 | 3403 | } else { |
| 3398 | 3404 | tvp = NULL; |
| ... | ... | @@ -3931,14 +3937,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, |
| 3931 | 3937 | struct timeval tv; |
| 3932 | 3938 | ret = get_errno(gettimeofday(&tv, NULL)); |
| 3933 | 3939 | if (!is_error(ret)) { |
| 3934 | - host_to_target_timeval(arg1, &tv); | |
| 3940 | + if (copy_to_user_timeval(arg1, &tv)) | |
| 3941 | + goto efault; | |
| 3935 | 3942 | } |
| 3936 | 3943 | } |
| 3937 | 3944 | break; |
| 3938 | 3945 | case TARGET_NR_settimeofday: |
| 3939 | 3946 | { |
| 3940 | 3947 | struct timeval tv; |
| 3941 | - target_to_host_timeval(&tv, arg1); | |
| 3948 | + if (copy_from_user_timeval(&tv, arg1)) | |
| 3949 | + goto efault; | |
| 3942 | 3950 | ret = get_errno(settimeofday(&tv, NULL)); |
| 3943 | 3951 | } |
| 3944 | 3952 | break; |
| ... | ... | @@ -4313,19 +4321,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, |
| 4313 | 4321 | |
| 4314 | 4322 | if (arg2) { |
| 4315 | 4323 | pvalue = &value; |
| 4316 | - target_to_host_timeval(&pvalue->it_interval, | |
| 4317 | - arg2); | |
| 4318 | - target_to_host_timeval(&pvalue->it_value, | |
| 4319 | - arg2 + sizeof(struct target_timeval)); | |
| 4324 | + if (copy_from_user_timeval(&pvalue->it_interval, arg2) | |
| 4325 | + || copy_from_user_timeval(&pvalue->it_value, | |
| 4326 | + arg2 + sizeof(struct target_timeval))) | |
| 4327 | + goto efault; | |
| 4320 | 4328 | } else { |
| 4321 | 4329 | pvalue = NULL; |
| 4322 | 4330 | } |
| 4323 | 4331 | ret = get_errno(setitimer(arg1, pvalue, &ovalue)); |
| 4324 | 4332 | if (!is_error(ret) && arg3) { |
| 4325 | - host_to_target_timeval(arg3, | |
| 4326 | - &ovalue.it_interval); | |
| 4327 | - host_to_target_timeval(arg3 + sizeof(struct target_timeval), | |
| 4328 | - &ovalue.it_value); | |
| 4333 | + if (copy_to_user_timeval(arg3, | |
| 4334 | + &ovalue.it_interval) | |
| 4335 | + || copy_to_user_timeval(arg3 + sizeof(struct target_timeval), | |
| 4336 | + &ovalue.it_value)) | |
| 4337 | + goto efault; | |
| 4329 | 4338 | } |
| 4330 | 4339 | } |
| 4331 | 4340 | break; |
| ... | ... | @@ -4335,10 +4344,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, |
| 4335 | 4344 | |
| 4336 | 4345 | ret = get_errno(getitimer(arg1, &value)); |
| 4337 | 4346 | if (!is_error(ret) && arg2) { |
| 4338 | - host_to_target_timeval(arg2, | |
| 4339 | - &value.it_interval); | |
| 4340 | - host_to_target_timeval(arg2 + sizeof(struct target_timeval), | |
| 4341 | - &value.it_value); | |
| 4347 | + if (copy_to_user_timeval(arg2, | |
| 4348 | + &value.it_interval) | |
| 4349 | + || copy_to_user_timeval(arg2 + sizeof(struct target_timeval), | |
| 4350 | + &value.it_value)) | |
| 4351 | + goto efault; | |
| 4342 | 4352 | } |
| 4343 | 4353 | } |
| 4344 | 4354 | break; | ... | ... |