Commit 788f5ec40d03a79ae7aa3335d7e3cfea72c502a8

Authored by ths
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;
... ...