diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2017-07-09 10:50:14 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-07-15 20:46:47 -0400 |
commit | 44ee454670122a959112caaa7aad86d8cacab1ff (patch) | |
tree | a1aa8a5a005186669761f206240d8a72b4fb7e1e | |
parent | a78ee9ed2f828e1960f366bf7ab204e7f19924c7 (diff) |
semtimedop(): move compat to native
... and finally kill the sodding compat_convert_timespec()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | include/linux/compat.h | 9 | ||||
-rw-r--r-- | ipc/compat.c | 10 | ||||
-rw-r--r-- | ipc/sem.c | 44 | ||||
-rw-r--r-- | kernel/compat.c | 23 |
4 files changed, 33 insertions, 53 deletions
diff --git a/include/linux/compat.h b/include/linux/compat.h index 5a6a109b4a50..edae425ca8c0 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h | |||
@@ -171,15 +171,6 @@ extern int get_compat_itimerspec64(struct itimerspec64 *its, | |||
171 | extern int put_compat_itimerspec64(const struct itimerspec64 *its, | 171 | extern int put_compat_itimerspec64(const struct itimerspec64 *its, |
172 | struct compat_itimerspec __user *uits); | 172 | struct compat_itimerspec __user *uits); |
173 | 173 | ||
174 | /* | ||
175 | * This function convert a timespec if necessary and returns a *user | ||
176 | * space* pointer. If no conversion is necessary, it returns the | ||
177 | * initial pointer. NULL is a legitimate argument and will always | ||
178 | * output NULL. | ||
179 | */ | ||
180 | extern int compat_convert_timespec(struct timespec __user **, | ||
181 | const void __user *); | ||
182 | |||
183 | struct compat_iovec { | 174 | struct compat_iovec { |
184 | compat_uptr_t iov_base; | 175 | compat_uptr_t iov_base; |
185 | compat_size_t iov_len; | 176 | compat_size_t iov_len; |
diff --git a/ipc/compat.c b/ipc/compat.c index 871d07da0a52..b17bf93d7b49 100644 --- a/ipc/compat.c +++ b/ipc/compat.c | |||
@@ -79,13 +79,3 @@ void to_compat_ipc_perm(struct compat_ipc_perm *to, struct ipc64_perm *from) | |||
79 | to->mode = from->mode; | 79 | to->mode = from->mode; |
80 | to->seq = from->seq; | 80 | to->seq = from->seq; |
81 | } | 81 | } |
82 | |||
83 | COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems, | ||
84 | unsigned, nsops, | ||
85 | const struct compat_timespec __user *, timeout) | ||
86 | { | ||
87 | struct timespec __user *ts64; | ||
88 | if (compat_convert_timespec(&ts64, timeout)) | ||
89 | return -EFAULT; | ||
90 | return sys_semtimedop(semid, tsems, nsops, ts64); | ||
91 | } | ||
@@ -1855,8 +1855,8 @@ out: | |||
1855 | return un; | 1855 | return un; |
1856 | } | 1856 | } |
1857 | 1857 | ||
1858 | SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, | 1858 | static long do_semtimedop(int semid, struct sembuf __user *tsops, |
1859 | unsigned, nsops, const struct timespec __user *, timeout) | 1859 | unsigned nsops, const struct timespec *timeout) |
1860 | { | 1860 | { |
1861 | int error = -EINVAL; | 1861 | int error = -EINVAL; |
1862 | struct sem_array *sma; | 1862 | struct sem_array *sma; |
@@ -1887,17 +1887,12 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, | |||
1887 | } | 1887 | } |
1888 | 1888 | ||
1889 | if (timeout) { | 1889 | if (timeout) { |
1890 | struct timespec _timeout; | 1890 | if (timeout->tv_sec < 0 || timeout->tv_nsec < 0 || |
1891 | if (copy_from_user(&_timeout, timeout, sizeof(*timeout))) { | 1891 | timeout->tv_nsec >= 1000000000L) { |
1892 | error = -EFAULT; | ||
1893 | goto out_free; | ||
1894 | } | ||
1895 | if (_timeout.tv_sec < 0 || _timeout.tv_nsec < 0 || | ||
1896 | _timeout.tv_nsec >= 1000000000L) { | ||
1897 | error = -EINVAL; | 1892 | error = -EINVAL; |
1898 | goto out_free; | 1893 | goto out_free; |
1899 | } | 1894 | } |
1900 | jiffies_left = timespec_to_jiffies(&_timeout); | 1895 | jiffies_left = timespec_to_jiffies(timeout); |
1901 | } | 1896 | } |
1902 | 1897 | ||
1903 | max = 0; | 1898 | max = 0; |
@@ -2112,10 +2107,37 @@ out_free: | |||
2112 | return error; | 2107 | return error; |
2113 | } | 2108 | } |
2114 | 2109 | ||
2110 | SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, | ||
2111 | unsigned, nsops, const struct timespec __user *, timeout) | ||
2112 | { | ||
2113 | if (timeout) { | ||
2114 | struct timespec ts; | ||
2115 | if (copy_from_user(&ts, timeout, sizeof(*timeout))) | ||
2116 | return -EFAULT; | ||
2117 | return do_semtimedop(semid, tsops, nsops, &ts); | ||
2118 | } | ||
2119 | return do_semtimedop(semid, tsops, nsops, NULL); | ||
2120 | } | ||
2121 | |||
2122 | #ifdef CONFIG_COMPAT | ||
2123 | COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems, | ||
2124 | unsigned, nsops, | ||
2125 | const struct compat_timespec __user *, timeout) | ||
2126 | { | ||
2127 | if (timeout) { | ||
2128 | struct timespec ts; | ||
2129 | if (compat_get_timespec(&ts, timeout)) | ||
2130 | return -EFAULT; | ||
2131 | return do_semtimedop(semid, tsems, nsops, &ts); | ||
2132 | } | ||
2133 | return do_semtimedop(semid, tsems, nsops, NULL); | ||
2134 | } | ||
2135 | #endif | ||
2136 | |||
2115 | SYSCALL_DEFINE3(semop, int, semid, struct sembuf __user *, tsops, | 2137 | SYSCALL_DEFINE3(semop, int, semid, struct sembuf __user *, tsops, |
2116 | unsigned, nsops) | 2138 | unsigned, nsops) |
2117 | { | 2139 | { |
2118 | return sys_semtimedop(semid, tsops, nsops, NULL); | 2140 | return do_semtimedop(semid, tsops, nsops, NULL); |
2119 | } | 2141 | } |
2120 | 2142 | ||
2121 | /* If CLONE_SYSVSEM is set, establish sharing of SEM_UNDO state between | 2143 | /* If CLONE_SYSVSEM is set, establish sharing of SEM_UNDO state between |
diff --git a/kernel/compat.c b/kernel/compat.c index 6f0a0e723a06..772e038d04d9 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
@@ -200,29 +200,6 @@ int compat_put_timespec(const struct timespec *ts, void __user *uts) | |||
200 | } | 200 | } |
201 | EXPORT_SYMBOL_GPL(compat_put_timespec); | 201 | EXPORT_SYMBOL_GPL(compat_put_timespec); |
202 | 202 | ||
203 | int compat_convert_timespec(struct timespec __user **kts, | ||
204 | const void __user *cts) | ||
205 | { | ||
206 | struct timespec ts; | ||
207 | struct timespec __user *uts; | ||
208 | |||
209 | if (!cts || COMPAT_USE_64BIT_TIME) { | ||
210 | *kts = (struct timespec __user *)cts; | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | uts = compat_alloc_user_space(sizeof(ts)); | ||
215 | if (!uts) | ||
216 | return -EFAULT; | ||
217 | if (compat_get_timespec(&ts, cts)) | ||
218 | return -EFAULT; | ||
219 | if (copy_to_user(uts, &ts, sizeof(ts))) | ||
220 | return -EFAULT; | ||
221 | |||
222 | *kts = uts; | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | int get_compat_itimerval(struct itimerval *o, const struct compat_itimerval __user *i) | 203 | int get_compat_itimerval(struct itimerval *o, const struct compat_itimerval __user *i) |
227 | { | 204 | { |
228 | struct compat_itimerval v32; | 205 | struct compat_itimerval v32; |