COMPAT_SYSCALL_DEFINE4(utimensat, unsigned int, dfd, const char __user *, filename, struct compat_timespec __user *, t, int, flags) { struct timespec tv[2]; if (t) { if (compat_get_timespec(&tv[0], &t[0]) || compat_get_timespec(&tv[1], &t[1])) return -EFAULT; if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT) return 0; } return do_utimes(dfd, filename, t ? tv : NULL, flags); }
COMPAT_SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val, struct compat_timespec __user *, utime, u32 __user *, uaddr2, u32, val3) { struct timespec ts; ktime_t t, *tp = NULL; int val2 = 0; int cmd = op & FUTEX_CMD_MASK; if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI || cmd == FUTEX_WAIT_BITSET || cmd == FUTEX_WAIT_REQUEUE_PI)) { if (compat_get_timespec(&ts, utime)) return -EFAULT; if (!timespec_valid(&ts)) return -EINVAL; t = timespec_to_ktime(ts); if (cmd == FUTEX_WAIT) t = ktime_add_safe(ktime_get(), t); tp = &t; } if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE || cmd == FUTEX_CMP_REQUEUE_PI || cmd == FUTEX_WAKE_OP) val2 = (int) (unsigned long) utime; return do_futex(uaddr, op, val, tp, uaddr2, val2, val3); }
static long alarm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct timespec ts; int rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_SET_AND_WAIT_COMPAT(0): case ANDROID_ALARM_SET_COMPAT(0): case ANDROID_ALARM_SET_RTC_COMPAT: if (compat_get_timespec(&ts, (void __user *)arg)) return -EFAULT; /* fall through */ case ANDROID_ALARM_GET_TIME_COMPAT(0): cmd = ANDROID_ALARM_COMPAT_TO_NORM(cmd); break; } rv = alarm_do_ioctl(file, cmd, &ts); if (rv) return rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_GET_TIME(0): /* NOTE: we modified cmd above */ if (compat_put_timespec(&ts, (void __user *)arg)) return -EFAULT; break; } return 0; }
COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp, struct compat_timespec __user *, rmtp) { struct timespec tu, rmt; mm_segment_t oldfs; long ret; if (compat_get_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); /* * hrtimer_nanosleep() can only return 0 or * -ERESTART_RESTARTBLOCK here because: * * - we call it with HRTIMER_MODE_REL and therefor exclude the * -ERESTARTNOHAND return path. * * - we supply the rmtp argument from the task stack (due to * the necessary compat conversion. So the update cannot * fail, which excludes the -EFAULT return path as well. If * it fails nevertheless we have a bigger problem and wont * reach this place anymore. * * - if the return value is 0, we do not have to update rmtp * because there is no remaining time. * * We check for -ERESTART_RESTARTBLOCK nevertheless if the * core implementation decides to return random nonsense. */ if (ret == -ERESTART_RESTARTBLOCK) { struct restart_block *restart = ¤t->restart_block; restart->fn = compat_nanosleep_restart; restart->nanosleep.compat_rmtp = rmtp; if (rmtp && compat_put_timespec(&rmt, rmtp)) return -EFAULT; } return ret; }
static long ach_ch_set_mode_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct achk_opt_32 *arg32 = (struct achk_opt_32 *)arg; struct achk_opt arg64; struct achk_opt *p = compat_alloc_user_space(sizeof(arg64)); int err; memset(&arg64, 0, sizeof(arg64)); err = 0; err |= copy_from_user(&arg64.options, &arg32->options, sizeof(arg64.options)); err |= compat_get_timespec(&arg64.reltime, &arg32->reltime); err |= copy_to_user(p, &arg64, sizeof(arg64)); if (err) return -EFAULT; return ach_ch_ioctl(file, ACH_CH_SET_MODE, (unsigned long)p); }
static long alarm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct timespec ts; struct rtc_wkalrm pwron_alm; int rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_SET_AND_WAIT_COMPAT(0): case ANDROID_ALARM_SET_COMPAT(0): case ANDROID_ALARM_SET_RTC_COMPAT: case ANDROID_ALARM_SET_IPO_COMPAT(0): if (compat_get_timespec(&ts, (void __user *)arg)) return -EFAULT; /* fall through */ case ANDROID_ALARM_GET_TIME_COMPAT(0): cmd = ANDROID_ALARM_COMPAT_TO_NORM(cmd); break; } rv = alarm_do_ioctl(file, cmd, &ts, &pwron_alm); if (rv) return rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_GET_TIME(0): /* NOTE: we modified cmd above */ if (compat_put_timespec(&ts, (void __user *)arg)) return -EFAULT; break; case ANDROID_ALARM_GET_POWER_ON: case ANDROID_ALARM_GET_POWER_ON_IPO: if (copy_to_user((void __user *)arg, &pwron_alm, sizeof(struct rtc_wkalrm))) { rv = -EFAULT; return rv; } break; } return 0; }
COMPAT_SYSCALL_DEFINE5(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 (timeout == NULL) return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, flags | MSG_CMSG_COMPAT, NULL); if (compat_get_timespec(&ktspec, timeout)) return -EFAULT; datagrams = __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, flags | MSG_CMSG_COMPAT, &ktspec); if (datagrams > 0 && compat_put_timespec(&ktspec, timeout)) datagrams = -EFAULT; return datagrams; }
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; }
asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg, unsigned vlen, unsigned int flags, struct compat_timespec __user *timeout) { int datagrams; struct timespec ktspec; if (flags & MSG_CMSG_COMPAT) return -EINVAL; if (timeout == NULL) return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, flags | MSG_CMSG_COMPAT, NULL); if (compat_get_timespec(&ktspec, timeout)) return -EFAULT; datagrams = __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, flags | MSG_CMSG_COMPAT, &ktspec); if (datagrams > 0 && compat_put_timespec(&ktspec, timeout)) datagrams = -EFAULT; return datagrams; }