diff options
author | Deepa Dinamani <deepa.kernel@gmail.com> | 2017-06-24 14:45:08 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-06-30 04:15:02 -0400 |
commit | 725816e8aabb1c183baa2bc9572ab9a0d26b9ea1 (patch) | |
tree | b86c9f9af37d937e8332e906b61a13be24ed2065 | |
parent | bff412036f457d8160eebada43199b8d987152d8 (diff) |
posix_clocks: Use get_itimerspec64() and put_itimerspec64()
Usage of these apis and their compat versions makes
the syscalls: timer_settime and timer_gettime and their
compat implementations simpler.
This patch also serves as a preparatory patch for changing
syscalls to use new time_t data types to support the
y2038 effort by isolating the processing of user pointers
through these apis.
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | kernel/time/posix-timers.c | 44 |
1 files changed, 16 insertions, 28 deletions
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 4b0fc3b0a1c4..13d6881f908b 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c | |||
@@ -739,13 +739,11 @@ static int do_timer_gettime(timer_t timer_id, struct itimerspec64 *setting) | |||
739 | SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, | 739 | SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, |
740 | struct itimerspec __user *, setting) | 740 | struct itimerspec __user *, setting) |
741 | { | 741 | { |
742 | struct itimerspec64 cur_setting64; | 742 | struct itimerspec64 cur_setting; |
743 | 743 | ||
744 | int ret = do_timer_gettime(timer_id, &cur_setting64); | 744 | int ret = do_timer_gettime(timer_id, &cur_setting); |
745 | if (!ret) { | 745 | if (!ret) { |
746 | struct itimerspec cur_setting; | 746 | if (put_itimerspec64(&cur_setting, setting)) |
747 | cur_setting = itimerspec64_to_itimerspec(&cur_setting64); | ||
748 | if (copy_to_user(setting, &cur_setting, sizeof (cur_setting))) | ||
749 | ret = -EFAULT; | 747 | ret = -EFAULT; |
750 | } | 748 | } |
751 | return ret; | 749 | return ret; |
@@ -755,13 +753,11 @@ SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, | |||
755 | COMPAT_SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, | 753 | COMPAT_SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, |
756 | struct compat_itimerspec __user *, setting) | 754 | struct compat_itimerspec __user *, setting) |
757 | { | 755 | { |
758 | struct itimerspec64 cur_setting64; | 756 | struct itimerspec64 cur_setting; |
759 | 757 | ||
760 | int ret = do_timer_gettime(timer_id, &cur_setting64); | 758 | int ret = do_timer_gettime(timer_id, &cur_setting); |
761 | if (!ret) { | 759 | if (!ret) { |
762 | struct itimerspec cur_setting; | 760 | if (put_compat_itimerspec64(&cur_setting, setting)) |
763 | cur_setting = itimerspec64_to_itimerspec(&cur_setting64); | ||
764 | if (put_compat_itimerspec(setting, &cur_setting)) | ||
765 | ret = -EFAULT; | 761 | ret = -EFAULT; |
766 | } | 762 | } |
767 | return ret; | 763 | return ret; |
@@ -907,23 +903,19 @@ SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags, | |||
907 | const struct itimerspec __user *, new_setting, | 903 | const struct itimerspec __user *, new_setting, |
908 | struct itimerspec __user *, old_setting) | 904 | struct itimerspec __user *, old_setting) |
909 | { | 905 | { |
910 | struct itimerspec64 new_spec64, old_spec64; | 906 | struct itimerspec64 new_spec, old_spec; |
911 | struct itimerspec64 *rtn = old_setting ? &old_spec64 : NULL; | 907 | struct itimerspec64 *rtn = old_setting ? &old_spec : NULL; |
912 | struct itimerspec new_spec; | ||
913 | int error = 0; | 908 | int error = 0; |
914 | 909 | ||
915 | if (!new_setting) | 910 | if (!new_setting) |
916 | return -EINVAL; | 911 | return -EINVAL; |
917 | 912 | ||
918 | if (copy_from_user(&new_spec, new_setting, sizeof (new_spec))) | 913 | if (get_itimerspec64(&new_spec, new_setting)) |
919 | return -EFAULT; | 914 | return -EFAULT; |
920 | new_spec64 = itimerspec_to_itimerspec64(&new_spec); | ||
921 | 915 | ||
922 | error = do_timer_settime(timer_id, flags, &new_spec64, rtn); | 916 | error = do_timer_settime(timer_id, flags, &new_spec, rtn); |
923 | if (!error && old_setting) { | 917 | if (!error && old_setting) { |
924 | struct itimerspec old_spec; | 918 | if (put_itimerspec64(&old_spec, old_setting)) |
925 | old_spec = itimerspec64_to_itimerspec(&old_spec64); | ||
926 | if (copy_to_user(old_setting, &old_spec, sizeof (old_spec))) | ||
927 | error = -EFAULT; | 919 | error = -EFAULT; |
928 | } | 920 | } |
929 | return error; | 921 | return error; |
@@ -934,22 +926,18 @@ COMPAT_SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags, | |||
934 | struct compat_itimerspec __user *, new, | 926 | struct compat_itimerspec __user *, new, |
935 | struct compat_itimerspec __user *, old) | 927 | struct compat_itimerspec __user *, old) |
936 | { | 928 | { |
937 | struct itimerspec64 new_spec64, old_spec64; | 929 | struct itimerspec64 new_spec, old_spec; |
938 | struct itimerspec64 *rtn = old ? &old_spec64 : NULL; | 930 | struct itimerspec64 *rtn = old ? &old_spec : NULL; |
939 | struct itimerspec new_spec; | ||
940 | int error = 0; | 931 | int error = 0; |
941 | 932 | ||
942 | if (!new) | 933 | if (!new) |
943 | return -EINVAL; | 934 | return -EINVAL; |
944 | if (get_compat_itimerspec(&new_spec, new)) | 935 | if (get_compat_itimerspec64(&new_spec, new)) |
945 | return -EFAULT; | 936 | return -EFAULT; |
946 | 937 | ||
947 | new_spec64 = itimerspec_to_itimerspec64(&new_spec); | 938 | error = do_timer_settime(timer_id, flags, &new_spec, rtn); |
948 | error = do_timer_settime(timer_id, flags, &new_spec64, rtn); | ||
949 | if (!error && old) { | 939 | if (!error && old) { |
950 | struct itimerspec old_spec; | 940 | if (put_compat_itimerspec64(&old_spec, old)) |
951 | old_spec = itimerspec64_to_itimerspec(&old_spec64); | ||
952 | if (put_compat_itimerspec(old, &old_spec)) | ||
953 | error = -EFAULT; | 941 | error = -EFAULT; |
954 | } | 942 | } |
955 | return error; | 943 | return error; |