cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

timerfd.c (14276B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 *  fs/timerfd.c
      4 *
      5 *  Copyright (C) 2007  Davide Libenzi <davidel@xmailserver.org>
      6 *
      7 *
      8 *  Thanks to Thomas Gleixner for code reviews and useful comments.
      9 *
     10 */
     11
     12#include <linux/alarmtimer.h>
     13#include <linux/file.h>
     14#include <linux/poll.h>
     15#include <linux/init.h>
     16#include <linux/fs.h>
     17#include <linux/sched.h>
     18#include <linux/kernel.h>
     19#include <linux/slab.h>
     20#include <linux/list.h>
     21#include <linux/spinlock.h>
     22#include <linux/time.h>
     23#include <linux/hrtimer.h>
     24#include <linux/anon_inodes.h>
     25#include <linux/timerfd.h>
     26#include <linux/syscalls.h>
     27#include <linux/compat.h>
     28#include <linux/rcupdate.h>
     29#include <linux/time_namespace.h>
     30
     31struct timerfd_ctx {
     32	union {
     33		struct hrtimer tmr;
     34		struct alarm alarm;
     35	} t;
     36	ktime_t tintv;
     37	ktime_t moffs;
     38	wait_queue_head_t wqh;
     39	u64 ticks;
     40	int clockid;
     41	short unsigned expired;
     42	short unsigned settime_flags;	/* to show in fdinfo */
     43	struct rcu_head rcu;
     44	struct list_head clist;
     45	spinlock_t cancel_lock;
     46	bool might_cancel;
     47};
     48
     49static LIST_HEAD(cancel_list);
     50static DEFINE_SPINLOCK(cancel_lock);
     51
     52static inline bool isalarm(struct timerfd_ctx *ctx)
     53{
     54	return ctx->clockid == CLOCK_REALTIME_ALARM ||
     55		ctx->clockid == CLOCK_BOOTTIME_ALARM;
     56}
     57
     58/*
     59 * This gets called when the timer event triggers. We set the "expired"
     60 * flag, but we do not re-arm the timer (in case it's necessary,
     61 * tintv != 0) until the timer is accessed.
     62 */
     63static void timerfd_triggered(struct timerfd_ctx *ctx)
     64{
     65	unsigned long flags;
     66
     67	spin_lock_irqsave(&ctx->wqh.lock, flags);
     68	ctx->expired = 1;
     69	ctx->ticks++;
     70	wake_up_locked_poll(&ctx->wqh, EPOLLIN);
     71	spin_unlock_irqrestore(&ctx->wqh.lock, flags);
     72}
     73
     74static enum hrtimer_restart timerfd_tmrproc(struct hrtimer *htmr)
     75{
     76	struct timerfd_ctx *ctx = container_of(htmr, struct timerfd_ctx,
     77					       t.tmr);
     78	timerfd_triggered(ctx);
     79	return HRTIMER_NORESTART;
     80}
     81
     82static enum alarmtimer_restart timerfd_alarmproc(struct alarm *alarm,
     83	ktime_t now)
     84{
     85	struct timerfd_ctx *ctx = container_of(alarm, struct timerfd_ctx,
     86					       t.alarm);
     87	timerfd_triggered(ctx);
     88	return ALARMTIMER_NORESTART;
     89}
     90
     91/*
     92 * Called when the clock was set to cancel the timers in the cancel
     93 * list. This will wake up processes waiting on these timers. The
     94 * wake-up requires ctx->ticks to be non zero, therefore we increment
     95 * it before calling wake_up_locked().
     96 */
     97void timerfd_clock_was_set(void)
     98{
     99	ktime_t moffs = ktime_mono_to_real(0);
    100	struct timerfd_ctx *ctx;
    101	unsigned long flags;
    102
    103	rcu_read_lock();
    104	list_for_each_entry_rcu(ctx, &cancel_list, clist) {
    105		if (!ctx->might_cancel)
    106			continue;
    107		spin_lock_irqsave(&ctx->wqh.lock, flags);
    108		if (ctx->moffs != moffs) {
    109			ctx->moffs = KTIME_MAX;
    110			ctx->ticks++;
    111			wake_up_locked_poll(&ctx->wqh, EPOLLIN);
    112		}
    113		spin_unlock_irqrestore(&ctx->wqh.lock, flags);
    114	}
    115	rcu_read_unlock();
    116}
    117
    118static void timerfd_resume_work(struct work_struct *work)
    119{
    120	timerfd_clock_was_set();
    121}
    122
    123static DECLARE_WORK(timerfd_work, timerfd_resume_work);
    124
    125/*
    126 * Invoked from timekeeping_resume(). Defer the actual update to work so
    127 * timerfd_clock_was_set() runs in task context.
    128 */
    129void timerfd_resume(void)
    130{
    131	schedule_work(&timerfd_work);
    132}
    133
    134static void __timerfd_remove_cancel(struct timerfd_ctx *ctx)
    135{
    136	if (ctx->might_cancel) {
    137		ctx->might_cancel = false;
    138		spin_lock(&cancel_lock);
    139		list_del_rcu(&ctx->clist);
    140		spin_unlock(&cancel_lock);
    141	}
    142}
    143
    144static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
    145{
    146	spin_lock(&ctx->cancel_lock);
    147	__timerfd_remove_cancel(ctx);
    148	spin_unlock(&ctx->cancel_lock);
    149}
    150
    151static bool timerfd_canceled(struct timerfd_ctx *ctx)
    152{
    153	if (!ctx->might_cancel || ctx->moffs != KTIME_MAX)
    154		return false;
    155	ctx->moffs = ktime_mono_to_real(0);
    156	return true;
    157}
    158
    159static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags)
    160{
    161	spin_lock(&ctx->cancel_lock);
    162	if ((ctx->clockid == CLOCK_REALTIME ||
    163	     ctx->clockid == CLOCK_REALTIME_ALARM) &&
    164	    (flags & TFD_TIMER_ABSTIME) && (flags & TFD_TIMER_CANCEL_ON_SET)) {
    165		if (!ctx->might_cancel) {
    166			ctx->might_cancel = true;
    167			spin_lock(&cancel_lock);
    168			list_add_rcu(&ctx->clist, &cancel_list);
    169			spin_unlock(&cancel_lock);
    170		}
    171	} else {
    172		__timerfd_remove_cancel(ctx);
    173	}
    174	spin_unlock(&ctx->cancel_lock);
    175}
    176
    177static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx)
    178{
    179	ktime_t remaining;
    180
    181	if (isalarm(ctx))
    182		remaining = alarm_expires_remaining(&ctx->t.alarm);
    183	else
    184		remaining = hrtimer_expires_remaining_adjusted(&ctx->t.tmr);
    185
    186	return remaining < 0 ? 0: remaining;
    187}
    188
    189static int timerfd_setup(struct timerfd_ctx *ctx, int flags,
    190			 const struct itimerspec64 *ktmr)
    191{
    192	enum hrtimer_mode htmode;
    193	ktime_t texp;
    194	int clockid = ctx->clockid;
    195
    196	htmode = (flags & TFD_TIMER_ABSTIME) ?
    197		HRTIMER_MODE_ABS: HRTIMER_MODE_REL;
    198
    199	texp = timespec64_to_ktime(ktmr->it_value);
    200	ctx->expired = 0;
    201	ctx->ticks = 0;
    202	ctx->tintv = timespec64_to_ktime(ktmr->it_interval);
    203
    204	if (isalarm(ctx)) {
    205		alarm_init(&ctx->t.alarm,
    206			   ctx->clockid == CLOCK_REALTIME_ALARM ?
    207			   ALARM_REALTIME : ALARM_BOOTTIME,
    208			   timerfd_alarmproc);
    209	} else {
    210		hrtimer_init(&ctx->t.tmr, clockid, htmode);
    211		hrtimer_set_expires(&ctx->t.tmr, texp);
    212		ctx->t.tmr.function = timerfd_tmrproc;
    213	}
    214
    215	if (texp != 0) {
    216		if (flags & TFD_TIMER_ABSTIME)
    217			texp = timens_ktime_to_host(clockid, texp);
    218		if (isalarm(ctx)) {
    219			if (flags & TFD_TIMER_ABSTIME)
    220				alarm_start(&ctx->t.alarm, texp);
    221			else
    222				alarm_start_relative(&ctx->t.alarm, texp);
    223		} else {
    224			hrtimer_start(&ctx->t.tmr, texp, htmode);
    225		}
    226
    227		if (timerfd_canceled(ctx))
    228			return -ECANCELED;
    229	}
    230
    231	ctx->settime_flags = flags & TFD_SETTIME_FLAGS;
    232	return 0;
    233}
    234
    235static int timerfd_release(struct inode *inode, struct file *file)
    236{
    237	struct timerfd_ctx *ctx = file->private_data;
    238
    239	timerfd_remove_cancel(ctx);
    240
    241	if (isalarm(ctx))
    242		alarm_cancel(&ctx->t.alarm);
    243	else
    244		hrtimer_cancel(&ctx->t.tmr);
    245	kfree_rcu(ctx, rcu);
    246	return 0;
    247}
    248
    249static __poll_t timerfd_poll(struct file *file, poll_table *wait)
    250{
    251	struct timerfd_ctx *ctx = file->private_data;
    252	__poll_t events = 0;
    253	unsigned long flags;
    254
    255	poll_wait(file, &ctx->wqh, wait);
    256
    257	spin_lock_irqsave(&ctx->wqh.lock, flags);
    258	if (ctx->ticks)
    259		events |= EPOLLIN;
    260	spin_unlock_irqrestore(&ctx->wqh.lock, flags);
    261
    262	return events;
    263}
    264
    265static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count,
    266			    loff_t *ppos)
    267{
    268	struct timerfd_ctx *ctx = file->private_data;
    269	ssize_t res;
    270	u64 ticks = 0;
    271
    272	if (count < sizeof(ticks))
    273		return -EINVAL;
    274	spin_lock_irq(&ctx->wqh.lock);
    275	if (file->f_flags & O_NONBLOCK)
    276		res = -EAGAIN;
    277	else
    278		res = wait_event_interruptible_locked_irq(ctx->wqh, ctx->ticks);
    279
    280	/*
    281	 * If clock has changed, we do not care about the
    282	 * ticks and we do not rearm the timer. Userspace must
    283	 * reevaluate anyway.
    284	 */
    285	if (timerfd_canceled(ctx)) {
    286		ctx->ticks = 0;
    287		ctx->expired = 0;
    288		res = -ECANCELED;
    289	}
    290
    291	if (ctx->ticks) {
    292		ticks = ctx->ticks;
    293
    294		if (ctx->expired && ctx->tintv) {
    295			/*
    296			 * If tintv != 0, this is a periodic timer that
    297			 * needs to be re-armed. We avoid doing it in the timer
    298			 * callback to avoid DoS attacks specifying a very
    299			 * short timer period.
    300			 */
    301			if (isalarm(ctx)) {
    302				ticks += alarm_forward_now(
    303					&ctx->t.alarm, ctx->tintv) - 1;
    304				alarm_restart(&ctx->t.alarm);
    305			} else {
    306				ticks += hrtimer_forward_now(&ctx->t.tmr,
    307							     ctx->tintv) - 1;
    308				hrtimer_restart(&ctx->t.tmr);
    309			}
    310		}
    311		ctx->expired = 0;
    312		ctx->ticks = 0;
    313	}
    314	spin_unlock_irq(&ctx->wqh.lock);
    315	if (ticks)
    316		res = put_user(ticks, (u64 __user *) buf) ? -EFAULT: sizeof(ticks);
    317	return res;
    318}
    319
    320#ifdef CONFIG_PROC_FS
    321static void timerfd_show(struct seq_file *m, struct file *file)
    322{
    323	struct timerfd_ctx *ctx = file->private_data;
    324	struct timespec64 value, interval;
    325
    326	spin_lock_irq(&ctx->wqh.lock);
    327	value = ktime_to_timespec64(timerfd_get_remaining(ctx));
    328	interval = ktime_to_timespec64(ctx->tintv);
    329	spin_unlock_irq(&ctx->wqh.lock);
    330
    331	seq_printf(m,
    332		   "clockid: %d\n"
    333		   "ticks: %llu\n"
    334		   "settime flags: 0%o\n"
    335		   "it_value: (%llu, %llu)\n"
    336		   "it_interval: (%llu, %llu)\n",
    337		   ctx->clockid,
    338		   (unsigned long long)ctx->ticks,
    339		   ctx->settime_flags,
    340		   (unsigned long long)value.tv_sec,
    341		   (unsigned long long)value.tv_nsec,
    342		   (unsigned long long)interval.tv_sec,
    343		   (unsigned long long)interval.tv_nsec);
    344}
    345#else
    346#define timerfd_show NULL
    347#endif
    348
    349#ifdef CONFIG_CHECKPOINT_RESTORE
    350static long timerfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
    351{
    352	struct timerfd_ctx *ctx = file->private_data;
    353	int ret = 0;
    354
    355	switch (cmd) {
    356	case TFD_IOC_SET_TICKS: {
    357		u64 ticks;
    358
    359		if (copy_from_user(&ticks, (u64 __user *)arg, sizeof(ticks)))
    360			return -EFAULT;
    361		if (!ticks)
    362			return -EINVAL;
    363
    364		spin_lock_irq(&ctx->wqh.lock);
    365		if (!timerfd_canceled(ctx)) {
    366			ctx->ticks = ticks;
    367			wake_up_locked_poll(&ctx->wqh, EPOLLIN);
    368		} else
    369			ret = -ECANCELED;
    370		spin_unlock_irq(&ctx->wqh.lock);
    371		break;
    372	}
    373	default:
    374		ret = -ENOTTY;
    375		break;
    376	}
    377
    378	return ret;
    379}
    380#else
    381#define timerfd_ioctl NULL
    382#endif
    383
    384static const struct file_operations timerfd_fops = {
    385	.release	= timerfd_release,
    386	.poll		= timerfd_poll,
    387	.read		= timerfd_read,
    388	.llseek		= noop_llseek,
    389	.show_fdinfo	= timerfd_show,
    390	.unlocked_ioctl	= timerfd_ioctl,
    391};
    392
    393static int timerfd_fget(int fd, struct fd *p)
    394{
    395	struct fd f = fdget(fd);
    396	if (!f.file)
    397		return -EBADF;
    398	if (f.file->f_op != &timerfd_fops) {
    399		fdput(f);
    400		return -EINVAL;
    401	}
    402	*p = f;
    403	return 0;
    404}
    405
    406SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
    407{
    408	int ufd;
    409	struct timerfd_ctx *ctx;
    410
    411	/* Check the TFD_* constants for consistency.  */
    412	BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC);
    413	BUILD_BUG_ON(TFD_NONBLOCK != O_NONBLOCK);
    414
    415	if ((flags & ~TFD_CREATE_FLAGS) ||
    416	    (clockid != CLOCK_MONOTONIC &&
    417	     clockid != CLOCK_REALTIME &&
    418	     clockid != CLOCK_REALTIME_ALARM &&
    419	     clockid != CLOCK_BOOTTIME &&
    420	     clockid != CLOCK_BOOTTIME_ALARM))
    421		return -EINVAL;
    422
    423	if ((clockid == CLOCK_REALTIME_ALARM ||
    424	     clockid == CLOCK_BOOTTIME_ALARM) &&
    425	    !capable(CAP_WAKE_ALARM))
    426		return -EPERM;
    427
    428	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
    429	if (!ctx)
    430		return -ENOMEM;
    431
    432	init_waitqueue_head(&ctx->wqh);
    433	spin_lock_init(&ctx->cancel_lock);
    434	ctx->clockid = clockid;
    435
    436	if (isalarm(ctx))
    437		alarm_init(&ctx->t.alarm,
    438			   ctx->clockid == CLOCK_REALTIME_ALARM ?
    439			   ALARM_REALTIME : ALARM_BOOTTIME,
    440			   timerfd_alarmproc);
    441	else
    442		hrtimer_init(&ctx->t.tmr, clockid, HRTIMER_MODE_ABS);
    443
    444	ctx->moffs = ktime_mono_to_real(0);
    445
    446	ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx,
    447			       O_RDWR | (flags & TFD_SHARED_FCNTL_FLAGS));
    448	if (ufd < 0)
    449		kfree(ctx);
    450
    451	return ufd;
    452}
    453
    454static int do_timerfd_settime(int ufd, int flags, 
    455		const struct itimerspec64 *new,
    456		struct itimerspec64 *old)
    457{
    458	struct fd f;
    459	struct timerfd_ctx *ctx;
    460	int ret;
    461
    462	if ((flags & ~TFD_SETTIME_FLAGS) ||
    463		 !itimerspec64_valid(new))
    464		return -EINVAL;
    465
    466	ret = timerfd_fget(ufd, &f);
    467	if (ret)
    468		return ret;
    469	ctx = f.file->private_data;
    470
    471	if (isalarm(ctx) && !capable(CAP_WAKE_ALARM)) {
    472		fdput(f);
    473		return -EPERM;
    474	}
    475
    476	timerfd_setup_cancel(ctx, flags);
    477
    478	/*
    479	 * We need to stop the existing timer before reprogramming
    480	 * it to the new values.
    481	 */
    482	for (;;) {
    483		spin_lock_irq(&ctx->wqh.lock);
    484
    485		if (isalarm(ctx)) {
    486			if (alarm_try_to_cancel(&ctx->t.alarm) >= 0)
    487				break;
    488		} else {
    489			if (hrtimer_try_to_cancel(&ctx->t.tmr) >= 0)
    490				break;
    491		}
    492		spin_unlock_irq(&ctx->wqh.lock);
    493
    494		if (isalarm(ctx))
    495			hrtimer_cancel_wait_running(&ctx->t.alarm.timer);
    496		else
    497			hrtimer_cancel_wait_running(&ctx->t.tmr);
    498	}
    499
    500	/*
    501	 * If the timer is expired and it's periodic, we need to advance it
    502	 * because the caller may want to know the previous expiration time.
    503	 * We do not update "ticks" and "expired" since the timer will be
    504	 * re-programmed again in the following timerfd_setup() call.
    505	 */
    506	if (ctx->expired && ctx->tintv) {
    507		if (isalarm(ctx))
    508			alarm_forward_now(&ctx->t.alarm, ctx->tintv);
    509		else
    510			hrtimer_forward_now(&ctx->t.tmr, ctx->tintv);
    511	}
    512
    513	old->it_value = ktime_to_timespec64(timerfd_get_remaining(ctx));
    514	old->it_interval = ktime_to_timespec64(ctx->tintv);
    515
    516	/*
    517	 * Re-program the timer to the new value ...
    518	 */
    519	ret = timerfd_setup(ctx, flags, new);
    520
    521	spin_unlock_irq(&ctx->wqh.lock);
    522	fdput(f);
    523	return ret;
    524}
    525
    526static int do_timerfd_gettime(int ufd, struct itimerspec64 *t)
    527{
    528	struct fd f;
    529	struct timerfd_ctx *ctx;
    530	int ret = timerfd_fget(ufd, &f);
    531	if (ret)
    532		return ret;
    533	ctx = f.file->private_data;
    534
    535	spin_lock_irq(&ctx->wqh.lock);
    536	if (ctx->expired && ctx->tintv) {
    537		ctx->expired = 0;
    538
    539		if (isalarm(ctx)) {
    540			ctx->ticks +=
    541				alarm_forward_now(
    542					&ctx->t.alarm, ctx->tintv) - 1;
    543			alarm_restart(&ctx->t.alarm);
    544		} else {
    545			ctx->ticks +=
    546				hrtimer_forward_now(&ctx->t.tmr, ctx->tintv)
    547				- 1;
    548			hrtimer_restart(&ctx->t.tmr);
    549		}
    550	}
    551	t->it_value = ktime_to_timespec64(timerfd_get_remaining(ctx));
    552	t->it_interval = ktime_to_timespec64(ctx->tintv);
    553	spin_unlock_irq(&ctx->wqh.lock);
    554	fdput(f);
    555	return 0;
    556}
    557
    558SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,
    559		const struct __kernel_itimerspec __user *, utmr,
    560		struct __kernel_itimerspec __user *, otmr)
    561{
    562	struct itimerspec64 new, old;
    563	int ret;
    564
    565	if (get_itimerspec64(&new, utmr))
    566		return -EFAULT;
    567	ret = do_timerfd_settime(ufd, flags, &new, &old);
    568	if (ret)
    569		return ret;
    570	if (otmr && put_itimerspec64(&old, otmr))
    571		return -EFAULT;
    572
    573	return ret;
    574}
    575
    576SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct __kernel_itimerspec __user *, otmr)
    577{
    578	struct itimerspec64 kotmr;
    579	int ret = do_timerfd_gettime(ufd, &kotmr);
    580	if (ret)
    581		return ret;
    582	return put_itimerspec64(&kotmr, otmr) ? -EFAULT : 0;
    583}
    584
    585#ifdef CONFIG_COMPAT_32BIT_TIME
    586SYSCALL_DEFINE4(timerfd_settime32, int, ufd, int, flags,
    587		const struct old_itimerspec32 __user *, utmr,
    588		struct old_itimerspec32 __user *, otmr)
    589{
    590	struct itimerspec64 new, old;
    591	int ret;
    592
    593	if (get_old_itimerspec32(&new, utmr))
    594		return -EFAULT;
    595	ret = do_timerfd_settime(ufd, flags, &new, &old);
    596	if (ret)
    597		return ret;
    598	if (otmr && put_old_itimerspec32(&old, otmr))
    599		return -EFAULT;
    600	return ret;
    601}
    602
    603SYSCALL_DEFINE2(timerfd_gettime32, int, ufd,
    604		struct old_itimerspec32 __user *, otmr)
    605{
    606	struct itimerspec64 kotmr;
    607	int ret = do_timerfd_gettime(ufd, &kotmr);
    608	if (ret)
    609		return ret;
    610	return put_old_itimerspec32(&kotmr, otmr) ? -EFAULT : 0;
    611}
    612#endif