diff options
Diffstat (limited to 'kernel/compat.c')
-rw-r--r-- | kernel/compat.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/kernel/compat.c b/kernel/compat.c index 72650e39b3e6..8eafe3eb50d9 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
@@ -27,6 +27,64 @@ | |||
27 | 27 | ||
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | 29 | ||
30 | /* | ||
31 | * Note that the native side is already converted to a timespec, because | ||
32 | * that's what we want anyway. | ||
33 | */ | ||
34 | static int compat_get_timeval(struct timespec *o, | ||
35 | struct compat_timeval __user *i) | ||
36 | { | ||
37 | long usec; | ||
38 | |||
39 | if (get_user(o->tv_sec, &i->tv_sec) || | ||
40 | get_user(usec, &i->tv_usec)) | ||
41 | return -EFAULT; | ||
42 | o->tv_nsec = usec * 1000; | ||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | static int compat_put_timeval(struct compat_timeval __user *o, | ||
47 | struct timeval *i) | ||
48 | { | ||
49 | return (put_user(i->tv_sec, &o->tv_sec) || | ||
50 | put_user(i->tv_usec, &o->tv_usec)) ? -EFAULT : 0; | ||
51 | } | ||
52 | |||
53 | asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, | ||
54 | struct timezone __user *tz) | ||
55 | { | ||
56 | if (tv) { | ||
57 | struct timeval ktv; | ||
58 | do_gettimeofday(&ktv); | ||
59 | if (compat_put_timeval(tv, &ktv)) | ||
60 | return -EFAULT; | ||
61 | } | ||
62 | if (tz) { | ||
63 | if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) | ||
64 | return -EFAULT; | ||
65 | } | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, | ||
71 | struct timezone __user *tz) | ||
72 | { | ||
73 | struct timespec kts; | ||
74 | struct timezone ktz; | ||
75 | |||
76 | if (tv) { | ||
77 | if (compat_get_timeval(&kts, tv)) | ||
78 | return -EFAULT; | ||
79 | } | ||
80 | if (tz) { | ||
81 | if (copy_from_user(&ktz, tz, sizeof(ktz))) | ||
82 | return -EFAULT; | ||
83 | } | ||
84 | |||
85 | return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); | ||
86 | } | ||
87 | |||
30 | int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts) | 88 | int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts) |
31 | { | 89 | { |
32 | return (!access_ok(VERIFY_READ, cts, sizeof(*cts)) || | 90 | return (!access_ok(VERIFY_READ, cts, sizeof(*cts)) || |