aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2017-07-09 10:50:14 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2017-07-15 20:46:47 -0400
commit44ee454670122a959112caaa7aad86d8cacab1ff (patch)
treea1aa8a5a005186669761f206240d8a72b4fb7e1e
parenta78ee9ed2f828e1960f366bf7ab204e7f19924c7 (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.h9
-rw-r--r--ipc/compat.c10
-rw-r--r--ipc/sem.c44
-rw-r--r--kernel/compat.c23
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,
171extern int put_compat_itimerspec64(const struct itimerspec64 *its, 171extern 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 */
180extern int compat_convert_timespec(struct timespec __user **,
181 const void __user *);
182
183struct compat_iovec { 174struct 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
83COMPAT_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}
diff --git a/ipc/sem.c b/ipc/sem.c
index fcf064d6046a..6b832b7fa9fc 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -1855,8 +1855,8 @@ out:
1855 return un; 1855 return un;
1856} 1856}
1857 1857
1858SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, 1858static 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
2110SYSCALL_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
2123COMPAT_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
2115SYSCALL_DEFINE3(semop, int, semid, struct sembuf __user *, tsops, 2137SYSCALL_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}
201EXPORT_SYMBOL_GPL(compat_put_timespec); 201EXPORT_SYMBOL_GPL(compat_put_timespec);
202 202
203int 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
226int get_compat_itimerval(struct itimerval *o, const struct compat_itimerval __user *i) 203int get_compat_itimerval(struct itimerval *o, const struct compat_itimerval __user *i)
227{ 204{
228 struct compat_itimerval v32; 205 struct compat_itimerval v32;