Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44ee4546 authored by Al Viro's avatar Al Viro
Browse files

semtimedop(): move compat to native



... and finally kill the sodding compat_convert_timespec()

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent a78ee9ed
Loading
Loading
Loading
Loading
+0 −9
Original line number Diff line number Diff line
@@ -171,15 +171,6 @@ extern int get_compat_itimerspec64(struct itimerspec64 *its,
extern int put_compat_itimerspec64(const struct itimerspec64 *its,
			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 {
	compat_uptr_t	iov_base;
	compat_size_t	iov_len;
+0 −10
Original line number Diff line number Diff line
@@ -79,13 +79,3 @@ void to_compat_ipc_perm(struct compat_ipc_perm *to, struct ipc64_perm *from)
	to->mode = from->mode;
	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);
}
+33 −11
Original line number Diff line number Diff line
@@ -1855,8 +1855,8 @@ static struct sem_undo *find_alloc_undo(struct ipc_namespace *ns, int semid)
	return un;
}

SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
		unsigned, nsops, const struct timespec __user *, timeout)
static long do_semtimedop(int semid, struct sembuf __user *tsops,
		unsigned nsops, const struct timespec *timeout)
{
	int error = -EINVAL;
	struct sem_array *sma;
@@ -1887,17 +1887,12 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
	}

	if (timeout) {
		struct timespec _timeout;
		if (copy_from_user(&_timeout, timeout, sizeof(*timeout))) {
			error = -EFAULT;
			goto out_free;
		}
		if (_timeout.tv_sec < 0 || _timeout.tv_nsec < 0 ||
			_timeout.tv_nsec >= 1000000000L) {
		if (timeout->tv_sec < 0 || timeout->tv_nsec < 0 ||
			timeout->tv_nsec >= 1000000000L) {
			error = -EINVAL;
			goto out_free;
		}
		jiffies_left = timespec_to_jiffies(&_timeout);
		jiffies_left = timespec_to_jiffies(timeout);
	}

	max = 0;
@@ -2112,10 +2107,37 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
	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,
		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
+0 −23
Original line number Diff line number Diff line
@@ -200,29 +200,6 @@ int compat_put_timespec(const struct timespec *ts, void __user *uts)
}
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)
{
	struct compat_itimerval v32;