int put_compat_itimerspec(struct compat_itimerspec __user *dst, const struct itimerspec *src) { if (put_compat_timespec(&src->it_interval, &dst->it_interval) || put_compat_timespec(&src->it_value, &dst->it_value)) return -EFAULT; return 0; }
asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg, unsigned int vlen, unsigned int flags, struct compat_timespec __user *timeout) { int datagrams; struct timespec ktspec; if (COMPAT_USE_64BIT_TIME) return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, flags | MSG_CMSG_COMPAT, (struct timespec *) timeout); if (timeout == NULL) return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, flags | MSG_CMSG_COMPAT, NULL); if (get_compat_timespec(&ktspec, timeout)) return -EFAULT; datagrams = __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, flags | MSG_CMSG_COMPAT, &ktspec); if (datagrams > 0 && put_compat_timespec(&ktspec, timeout)) datagrams = -EFAULT; return datagrams; }
int compat_put_timespec(const struct timespec *ts, void __user *uts) { if (COMPAT_USE_64BIT_TIME) return copy_to_user(uts, ts, sizeof *ts) ? -EFAULT : 0; else return put_compat_timespec(ts, uts); }
asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp, struct compat_timespec __user *rmtp) { struct timespec tu, rmt; mm_segment_t oldfs; long ret; if (get_compat_timespec(&tu, rqtp)) return -EFAULT; if (!timespec_valid(&tu)) return -EINVAL; oldfs = get_fs(); set_fs(KERNEL_DS); ret = hrtimer_nanosleep(&tu, rmtp ? (struct timespec __user *)&rmt : NULL, HRTIMER_MODE_REL, CLOCK_MONOTONIC); set_fs(oldfs); if (ret) { struct restart_block *restart = ¤t_thread_info()->restart_block; restart->fn = compat_nanosleep_restart; restart->nanosleep.compat_rmtp = rmtp; if (rmtp && put_compat_timespec(&rmt, rmtp)) return -EFAULT; } return ret; }
asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp, struct compat_timespec __user *rmtp) { struct timespec t; struct restart_block *restart; unsigned long expire; if (get_compat_timespec(&t, rqtp)) return -EFAULT; if ((t.tv_nsec >= 1000000000L) || (t.tv_nsec < 0) || (t.tv_sec < 0)) return -EINVAL; expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec); expire = schedule_timeout_interruptible(expire); if (expire == 0) return 0; if (rmtp) { jiffies_to_timespec(expire, &t); if (put_compat_timespec(&t, rmtp)) return -EFAULT; } restart = ¤t_thread_info()->restart_block; restart->fn = compat_nanosleep_restart; restart->arg0 = jiffies + expire; restart->arg1 = (unsigned long) rmtp; return -ERESTART_RESTARTBLOCK; }
long compat_put_v4l2_event_data(struct v4l2_event __user *pdata, struct v4l2_event32 __user *pdata32) { long ret = 0; compat_uint_t type; compat_uint_t pending; compat_uint_t sequence; struct timespec timestamp; compat_uint_t id; if (!access_ok(VERIFY_WRITE, pdata32, sizeof(struct v4l2_event32))) return -EFAULT; ret = get_user(type, &pdata->type); ret |= put_user(type, &pdata32->type); ret |= copy_in_user(&pdata32->u, &pdata->u, sizeof(pdata->u)); ret |= get_user(pending, &pdata->pending); ret |= put_user(pending, &pdata32->pending); ret |= get_user(sequence, &pdata->sequence); ret |= put_user(sequence, &pdata32->sequence); /* ret |= get_compat_timespec(×tamp, &pdata->timestamp); */ ret |= copy_from_user(×tamp, &pdata->timestamp, sizeof(timestamp)); ret |= put_compat_timespec(×tamp, &pdata32->timestamp); ret |= get_user(id, &pdata->id); ret |= put_user(id, &pdata32->id); ret |= copy_in_user(pdata32->reserved, pdata->reserved, 8 * sizeof(__u32)); return ret; }
asmlinkage long sys32_sched_rr_get_interval(pid_t pid, struct compat_timespec __user *interval) { struct timespec t; int ret; KERNEL_SYSCALL(ret, sys_sched_rr_get_interval, pid, (struct timespec __user *)&t); if (put_compat_timespec(&t, interval)) return -EFAULT; return ret; }
long compat_put_v4l2_event_data(struct v4l2_event *kp, struct v4l2_event32 __user *up) { long ret = 0; ret = put_user(kp->type, &up->type); ret |= copy_in_user(&up->u, &kp->u, sizeof(kp->u)); ret |= put_user(kp->pending, &up->pending); ret |= put_user(kp->sequence, &up->sequence); ret |= put_compat_timespec(&kp->timestamp, &up->timestamp); ret |= put_user(kp->id, &up->id); ret |= copy_in_user(up->reserved, kp->reserved, 8 * sizeof(__u32)); return ret; }
asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval) { struct timespec t; int ret; mm_segment_t old_fs = get_fs (); set_fs (KERNEL_DS); ret = sys_sched_rr_get_interval(pid, (struct timespec __user *) &t); set_fs (old_fs); if (put_compat_timespec(&t, interval)) return -EFAULT; return ret; }
static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *up) { if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_event32)) || put_user(kp->type, &up->type) || copy_to_user(&up->u, &kp->u, sizeof(kp->u)) || put_user(kp->pending, &up->pending) || put_user(kp->sequence, &up->sequence) || put_compat_timespec(&kp->timestamp, &up->timestamp) || put_user(kp->id, &up->id) || copy_to_user(up->reserved, kp->reserved, 8 * sizeof(__u32))) return -EFAULT; return 0; }
/* Note: it is necessary to treat pid as an unsigned int, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ asmlinkage long compat_sys_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval) { struct timespec t; int ret; mm_segment_t old_fs = get_fs (); /* The __user pointer cast is valid because of the set_fs() */ set_fs (KERNEL_DS); ret = sys_sched_rr_get_interval((int)pid, (struct timespec __user *) &t); set_fs (old_fs); if (put_compat_timespec(&t, interval)) return -EFAULT; return ret; }
static int sis33_put_compat_acq_list(struct sis33_compat_acq_list __user *compat_list, struct sis33_acq_list __user *list) { struct sis33_compat_acq __user *compat_acqs; struct timeval ktime; struct timespec ts; compat_uptr_t uptr; u32 n_acqs; u32 uint; int err; int i; if (!access_ok(VERIFY_READ, list, sizeof(*list)) || !access_ok(VERIFY_WRITE, compat_list, sizeof(*compat_list))) return -EFAULT; err = 0; err |= __get_user(uint, &list->segment); err |= __put_user(uint, &compat_list->segment); err |= __get_user(uint, &list->channel); err |= __put_user(uint, &compat_list->channel); err |= __get_user(uint, &list->n_acqs); err |= __put_user(uint, &compat_list->n_acqs); n_acqs = uint; err |= __get_user(uint, &list->flags); err |= __put_user(uint, &compat_list->flags); err |= copy_from_user(&ts, &list->timeout, sizeof(ts)); err |= put_compat_timespec(&ts, &compat_list->timeout); err |= __get_user(ktime.tv_sec, &list->endtime.tv_sec); err |= __put_user(ktime.tv_sec, &compat_list->endtime.tv_sec); err |= __get_user(ktime.tv_usec, &list->endtime.tv_usec); err |= __put_user(ktime.tv_usec, &compat_list->endtime.tv_usec); err |= __get_user(uptr, &compat_list->acqs); compat_acqs = compat_ptr(uptr); if (err) return -EFAULT; for (i = 0; i < n_acqs; i++) { err = sis33_put_compat_acq(&compat_acqs[i], &list->acqs[i]); if (err) return err; } return 0; }
static long compat_nanosleep_restart(struct restart_block *restart) { struct compat_timespec __user *rmtp; struct timespec rmt; mm_segment_t oldfs; long ret; restart->nanosleep.rmtp = (struct timespec __user *) &rmt; oldfs = get_fs(); set_fs(KERNEL_DS); ret = hrtimer_nanosleep_restart(restart); set_fs(oldfs); if (ret) { rmtp = restart->nanosleep.compat_rmtp; if (rmtp && put_compat_timespec(&rmt, rmtp)) return -EFAULT; } return ret; }