diff options
Diffstat (limited to 'kernel/compat.c')
-rw-r--r-- | kernel/compat.c | 136 |
1 files changed, 88 insertions, 48 deletions
diff --git a/kernel/compat.c b/kernel/compat.c index c9e2ec0b34a..38b1d2c1cbe 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
@@ -52,6 +52,64 @@ static int compat_put_timeval(struct compat_timeval __user *o, | |||
52 | put_user(i->tv_usec, &o->tv_usec)) ? -EFAULT : 0; | 52 | put_user(i->tv_usec, &o->tv_usec)) ? -EFAULT : 0; |
53 | } | 53 | } |
54 | 54 | ||
55 | static int compat_get_timex(struct timex *txc, struct compat_timex __user *utp) | ||
56 | { | ||
57 | memset(txc, 0, sizeof(struct timex)); | ||
58 | |||
59 | if (!access_ok(VERIFY_READ, utp, sizeof(struct compat_timex)) || | ||
60 | __get_user(txc->modes, &utp->modes) || | ||
61 | __get_user(txc->offset, &utp->offset) || | ||
62 | __get_user(txc->freq, &utp->freq) || | ||
63 | __get_user(txc->maxerror, &utp->maxerror) || | ||
64 | __get_user(txc->esterror, &utp->esterror) || | ||
65 | __get_user(txc->status, &utp->status) || | ||
66 | __get_user(txc->constant, &utp->constant) || | ||
67 | __get_user(txc->precision, &utp->precision) || | ||
68 | __get_user(txc->tolerance, &utp->tolerance) || | ||
69 | __get_user(txc->time.tv_sec, &utp->time.tv_sec) || | ||
70 | __get_user(txc->time.tv_usec, &utp->time.tv_usec) || | ||
71 | __get_user(txc->tick, &utp->tick) || | ||
72 | __get_user(txc->ppsfreq, &utp->ppsfreq) || | ||
73 | __get_user(txc->jitter, &utp->jitter) || | ||
74 | __get_user(txc->shift, &utp->shift) || | ||
75 | __get_user(txc->stabil, &utp->stabil) || | ||
76 | __get_user(txc->jitcnt, &utp->jitcnt) || | ||
77 | __get_user(txc->calcnt, &utp->calcnt) || | ||
78 | __get_user(txc->errcnt, &utp->errcnt) || | ||
79 | __get_user(txc->stbcnt, &utp->stbcnt)) | ||
80 | return -EFAULT; | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static int compat_put_timex(struct compat_timex __user *utp, struct timex *txc) | ||
86 | { | ||
87 | if (!access_ok(VERIFY_WRITE, utp, sizeof(struct compat_timex)) || | ||
88 | __put_user(txc->modes, &utp->modes) || | ||
89 | __put_user(txc->offset, &utp->offset) || | ||
90 | __put_user(txc->freq, &utp->freq) || | ||
91 | __put_user(txc->maxerror, &utp->maxerror) || | ||
92 | __put_user(txc->esterror, &utp->esterror) || | ||
93 | __put_user(txc->status, &utp->status) || | ||
94 | __put_user(txc->constant, &utp->constant) || | ||
95 | __put_user(txc->precision, &utp->precision) || | ||
96 | __put_user(txc->tolerance, &utp->tolerance) || | ||
97 | __put_user(txc->time.tv_sec, &utp->time.tv_sec) || | ||
98 | __put_user(txc->time.tv_usec, &utp->time.tv_usec) || | ||
99 | __put_user(txc->tick, &utp->tick) || | ||
100 | __put_user(txc->ppsfreq, &utp->ppsfreq) || | ||
101 | __put_user(txc->jitter, &utp->jitter) || | ||
102 | __put_user(txc->shift, &utp->shift) || | ||
103 | __put_user(txc->stabil, &utp->stabil) || | ||
104 | __put_user(txc->jitcnt, &utp->jitcnt) || | ||
105 | __put_user(txc->calcnt, &utp->calcnt) || | ||
106 | __put_user(txc->errcnt, &utp->errcnt) || | ||
107 | __put_user(txc->stbcnt, &utp->stbcnt) || | ||
108 | __put_user(txc->tai, &utp->tai)) | ||
109 | return -EFAULT; | ||
110 | return 0; | ||
111 | } | ||
112 | |||
55 | asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, | 113 | asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, |
56 | struct timezone __user *tz) | 114 | struct timezone __user *tz) |
57 | { | 115 | { |
@@ -617,6 +675,29 @@ long compat_sys_clock_gettime(clockid_t which_clock, | |||
617 | return err; | 675 | return err; |
618 | } | 676 | } |
619 | 677 | ||
678 | long compat_sys_clock_adjtime(clockid_t which_clock, | ||
679 | struct compat_timex __user *utp) | ||
680 | { | ||
681 | struct timex txc; | ||
682 | mm_segment_t oldfs; | ||
683 | int err, ret; | ||
684 | |||
685 | err = compat_get_timex(&txc, utp); | ||
686 | if (err) | ||
687 | return err; | ||
688 | |||
689 | oldfs = get_fs(); | ||
690 | set_fs(KERNEL_DS); | ||
691 | ret = sys_clock_adjtime(which_clock, (struct timex __user *) &txc); | ||
692 | set_fs(oldfs); | ||
693 | |||
694 | err = compat_put_timex(utp, &txc); | ||
695 | if (err) | ||
696 | return err; | ||
697 | |||
698 | return ret; | ||
699 | } | ||
700 | |||
620 | long compat_sys_clock_getres(clockid_t which_clock, | 701 | long compat_sys_clock_getres(clockid_t which_clock, |
621 | struct compat_timespec __user *tp) | 702 | struct compat_timespec __user *tp) |
622 | { | 703 | { |
@@ -951,58 +1032,17 @@ asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, compat | |||
951 | asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp) | 1032 | asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp) |
952 | { | 1033 | { |
953 | struct timex txc; | 1034 | struct timex txc; |
954 | int ret; | 1035 | int err, ret; |
955 | |||
956 | memset(&txc, 0, sizeof(struct timex)); | ||
957 | 1036 | ||
958 | if (!access_ok(VERIFY_READ, utp, sizeof(struct compat_timex)) || | 1037 | err = compat_get_timex(&txc, utp); |
959 | __get_user(txc.modes, &utp->modes) || | 1038 | if (err) |
960 | __get_user(txc.offset, &utp->offset) || | 1039 | return err; |
961 | __get_user(txc.freq, &utp->freq) || | ||
962 | __get_user(txc.maxerror, &utp->maxerror) || | ||
963 | __get_user(txc.esterror, &utp->esterror) || | ||
964 | __get_user(txc.status, &utp->status) || | ||
965 | __get_user(txc.constant, &utp->constant) || | ||
966 | __get_user(txc.precision, &utp->precision) || | ||
967 | __get_user(txc.tolerance, &utp->tolerance) || | ||
968 | __get_user(txc.time.tv_sec, &utp->time.tv_sec) || | ||
969 | __get_user(txc.time.tv_usec, &utp->time.tv_usec) || | ||
970 | __get_user(txc.tick, &utp->tick) || | ||
971 | __get_user(txc.ppsfreq, &utp->ppsfreq) || | ||
972 | __get_user(txc.jitter, &utp->jitter) || | ||
973 | __get_user(txc.shift, &utp->shift) || | ||
974 | __get_user(txc.stabil, &utp->stabil) || | ||
975 | __get_user(txc.jitcnt, &utp->jitcnt) || | ||
976 | __get_user(txc.calcnt, &utp->calcnt) || | ||
977 | __get_user(txc.errcnt, &utp->errcnt) || | ||
978 | __get_user(txc.stbcnt, &utp->stbcnt)) | ||
979 | return -EFAULT; | ||
980 | 1040 | ||
981 | ret = do_adjtimex(&txc); | 1041 | ret = do_adjtimex(&txc); |
982 | 1042 | ||
983 | if (!access_ok(VERIFY_WRITE, utp, sizeof(struct compat_timex)) || | 1043 | err = compat_put_timex(utp, &txc); |
984 | __put_user(txc.modes, &utp->modes) || | 1044 | if (err) |
985 | __put_user(txc.offset, &utp->offset) || | 1045 | return err; |
986 | __put_user(txc.freq, &utp->freq) || | ||
987 | __put_user(txc.maxerror, &utp->maxerror) || | ||
988 | __put_user(txc.esterror, &utp->esterror) || | ||
989 | __put_user(txc.status, &utp->status) || | ||
990 | __put_user(txc.constant, &utp->constant) || | ||
991 | __put_user(txc.precision, &utp->precision) || | ||
992 | __put_user(txc.tolerance, &utp->tolerance) || | ||
993 | __put_user(txc.time.tv_sec, &utp->time.tv_sec) || | ||
994 | __put_user(txc.time.tv_usec, &utp->time.tv_usec) || | ||
995 | __put_user(txc.tick, &utp->tick) || | ||
996 | __put_user(txc.ppsfreq, &utp->ppsfreq) || | ||
997 | __put_user(txc.jitter, &utp->jitter) || | ||
998 | __put_user(txc.shift, &utp->shift) || | ||
999 | __put_user(txc.stabil, &utp->stabil) || | ||
1000 | __put_user(txc.jitcnt, &utp->jitcnt) || | ||
1001 | __put_user(txc.calcnt, &utp->calcnt) || | ||
1002 | __put_user(txc.errcnt, &utp->errcnt) || | ||
1003 | __put_user(txc.stbcnt, &utp->stbcnt) || | ||
1004 | __put_user(txc.tai, &utp->tai)) | ||
1005 | ret = -EFAULT; | ||
1006 | 1046 | ||
1007 | return ret; | 1047 | return ret; |
1008 | } | 1048 | } |