semtimedop(): move compat to native
... and finally kill the sodding compat_convert_timespec() Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
a78ee9ed2f
commit
44ee454670
@ -171,15 +171,6 @@ extern int get_compat_itimerspec64(struct itimerspec64 *its,
|
|||||||
extern int put_compat_itimerspec64(const struct itimerspec64 *its,
|
extern int put_compat_itimerspec64(const struct itimerspec64 *its,
|
||||||
struct compat_itimerspec __user *uits);
|
struct compat_itimerspec __user *uits);
|
||||||
|
|
||||||
/*
|
|
||||||
* This function convert a timespec if necessary and returns a *user
|
|
||||||
* space* pointer. If no conversion is necessary, it returns the
|
|
||||||
* initial pointer. NULL is a legitimate argument and will always
|
|
||||||
* output NULL.
|
|
||||||
*/
|
|
||||||
extern int compat_convert_timespec(struct timespec __user **,
|
|
||||||
const void __user *);
|
|
||||||
|
|
||||||
struct compat_iovec {
|
struct compat_iovec {
|
||||||
compat_uptr_t iov_base;
|
compat_uptr_t iov_base;
|
||||||
compat_size_t iov_len;
|
compat_size_t iov_len;
|
||||||
|
10
ipc/compat.c
10
ipc/compat.c
@ -79,13 +79,3 @@ void to_compat_ipc_perm(struct compat_ipc_perm *to, struct ipc64_perm *from)
|
|||||||
to->mode = from->mode;
|
to->mode = from->mode;
|
||||||
to->seq = from->seq;
|
to->seq = from->seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems,
|
|
||||||
unsigned, nsops,
|
|
||||||
const struct compat_timespec __user *, timeout)
|
|
||||||
{
|
|
||||||
struct timespec __user *ts64;
|
|
||||||
if (compat_convert_timespec(&ts64, timeout))
|
|
||||||
return -EFAULT;
|
|
||||||
return sys_semtimedop(semid, tsems, nsops, ts64);
|
|
||||||
}
|
|
||||||
|
44
ipc/sem.c
44
ipc/sem.c
@ -1855,8 +1855,8 @@ static struct sem_undo *find_alloc_undo(struct ipc_namespace *ns, int semid)
|
|||||||
return un;
|
return un;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
|
static long do_semtimedop(int semid, struct sembuf __user *tsops,
|
||||||
unsigned, nsops, const struct timespec __user *, timeout)
|
unsigned nsops, const struct timespec *timeout)
|
||||||
{
|
{
|
||||||
int error = -EINVAL;
|
int error = -EINVAL;
|
||||||
struct sem_array *sma;
|
struct sem_array *sma;
|
||||||
@ -1887,17 +1887,12 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (timeout) {
|
if (timeout) {
|
||||||
struct timespec _timeout;
|
if (timeout->tv_sec < 0 || timeout->tv_nsec < 0 ||
|
||||||
if (copy_from_user(&_timeout, timeout, sizeof(*timeout))) {
|
timeout->tv_nsec >= 1000000000L) {
|
||||||
error = -EFAULT;
|
|
||||||
goto out_free;
|
|
||||||
}
|
|
||||||
if (_timeout.tv_sec < 0 || _timeout.tv_nsec < 0 ||
|
|
||||||
_timeout.tv_nsec >= 1000000000L) {
|
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
jiffies_left = timespec_to_jiffies(&_timeout);
|
jiffies_left = timespec_to_jiffies(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
max = 0;
|
max = 0;
|
||||||
@ -2112,10 +2107,37 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
|
||||||
|
unsigned, nsops, const struct timespec __user *, timeout)
|
||||||
|
{
|
||||||
|
if (timeout) {
|
||||||
|
struct timespec ts;
|
||||||
|
if (copy_from_user(&ts, timeout, sizeof(*timeout)))
|
||||||
|
return -EFAULT;
|
||||||
|
return do_semtimedop(semid, tsops, nsops, &ts);
|
||||||
|
}
|
||||||
|
return do_semtimedop(semid, tsops, nsops, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems,
|
||||||
|
unsigned, nsops,
|
||||||
|
const struct compat_timespec __user *, timeout)
|
||||||
|
{
|
||||||
|
if (timeout) {
|
||||||
|
struct timespec ts;
|
||||||
|
if (compat_get_timespec(&ts, timeout))
|
||||||
|
return -EFAULT;
|
||||||
|
return do_semtimedop(semid, tsems, nsops, &ts);
|
||||||
|
}
|
||||||
|
return do_semtimedop(semid, tsems, nsops, NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SYSCALL_DEFINE3(semop, int, semid, struct sembuf __user *, tsops,
|
SYSCALL_DEFINE3(semop, int, semid, struct sembuf __user *, tsops,
|
||||||
unsigned, nsops)
|
unsigned, nsops)
|
||||||
{
|
{
|
||||||
return sys_semtimedop(semid, tsops, nsops, NULL);
|
return do_semtimedop(semid, tsops, nsops, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If CLONE_SYSVSEM is set, establish sharing of SEM_UNDO state between
|
/* If CLONE_SYSVSEM is set, establish sharing of SEM_UNDO state between
|
||||||
|
@ -200,29 +200,6 @@ int compat_put_timespec(const struct timespec *ts, void __user *uts)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(compat_put_timespec);
|
EXPORT_SYMBOL_GPL(compat_put_timespec);
|
||||||
|
|
||||||
int compat_convert_timespec(struct timespec __user **kts,
|
|
||||||
const void __user *cts)
|
|
||||||
{
|
|
||||||
struct timespec ts;
|
|
||||||
struct timespec __user *uts;
|
|
||||||
|
|
||||||
if (!cts || COMPAT_USE_64BIT_TIME) {
|
|
||||||
*kts = (struct timespec __user *)cts;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uts = compat_alloc_user_space(sizeof(ts));
|
|
||||||
if (!uts)
|
|
||||||
return -EFAULT;
|
|
||||||
if (compat_get_timespec(&ts, cts))
|
|
||||||
return -EFAULT;
|
|
||||||
if (copy_to_user(uts, &ts, sizeof(ts)))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
*kts = uts;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_compat_itimerval(struct itimerval *o, const struct compat_itimerval __user *i)
|
int get_compat_itimerval(struct itimerval *o, const struct compat_itimerval __user *i)
|
||||||
{
|
{
|
||||||
struct compat_itimerval v32;
|
struct compat_itimerval v32;
|
||||||
|
Loading…
Reference in New Issue
Block a user