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,30 +550,34 @@ static inline abi_long host_to_target_rusage(abi_ulong target_addr,
550 return 0; 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 struct target_timeval *target_tv; 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 return -TARGET_EFAULT; 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 return 0; 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 struct target_timeval *target_tv; 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 return -TARGET_EFAULT; 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 return 0; 582 return 0;
579 } 583 }
@@ -612,7 +616,8 @@ static abi_long do_select(int n, @@ -612,7 +616,8 @@ static abi_long do_select(int n,
612 } 616 }
613 617
614 if (target_tv_addr) { 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 tv_ptr = &tv; 621 tv_ptr = &tv;
617 } else { 622 } else {
618 tv_ptr = NULL; 623 tv_ptr = NULL;
@@ -628,8 +633,8 @@ static abi_long do_select(int n, @@ -628,8 +633,8 @@ static abi_long do_select(int n,
628 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n)) 633 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
629 return -TARGET_EFAULT; 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 return ret; 640 return ret;
@@ -3390,9 +3395,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3390,9 +3395,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3390 { 3395 {
3391 struct timeval *tvp, tv[2]; 3396 struct timeval *tvp, tv[2];
3392 if (arg2) { 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 tvp = tv; 3402 tvp = tv;
3397 } else { 3403 } else {
3398 tvp = NULL; 3404 tvp = NULL;
@@ -3931,14 +3937,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3931,14 +3937,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3931 struct timeval tv; 3937 struct timeval tv;
3932 ret = get_errno(gettimeofday(&tv, NULL)); 3938 ret = get_errno(gettimeofday(&tv, NULL));
3933 if (!is_error(ret)) { 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 break; 3944 break;
3938 case TARGET_NR_settimeofday: 3945 case TARGET_NR_settimeofday:
3939 { 3946 {
3940 struct timeval tv; 3947 struct timeval tv;
3941 - target_to_host_timeval(&tv, arg1); 3948 + if (copy_from_user_timeval(&tv, arg1))
  3949 + goto efault;
3942 ret = get_errno(settimeofday(&tv, NULL)); 3950 ret = get_errno(settimeofday(&tv, NULL));
3943 } 3951 }
3944 break; 3952 break;
@@ -4313,19 +4321,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4313,19 +4321,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4313 4321
4314 if (arg2) { 4322 if (arg2) {
4315 pvalue = &value; 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 } else { 4328 } else {
4321 pvalue = NULL; 4329 pvalue = NULL;
4322 } 4330 }
4323 ret = get_errno(setitimer(arg1, pvalue, &ovalue)); 4331 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4324 if (!is_error(ret) && arg3) { 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 break; 4340 break;
@@ -4335,10 +4344,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4335,10 +4344,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4335 4344
4336 ret = get_errno(getitimer(arg1, &value)); 4345 ret = get_errno(getitimer(arg1, &value));
4337 if (!is_error(ret) && arg2) { 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 break; 4354 break;