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