| .. | .. | 
|---|
| 26 | 26 | #include <linux/syscalls.h> | 
|---|
| 27 | 27 | #include <linux/compat.h> | 
|---|
| 28 | 28 | #include <linux/rcupdate.h> | 
|---|
|  | 29 | +#include <linux/time_namespace.h> | 
|---|
|  | 30 | + | 
|---|
|  | 31 | +#include <trace/hooks/fs.h> | 
|---|
| 29 | 32 |  | 
|---|
| 30 | 33 | struct timerfd_ctx { | 
|---|
| 31 | 34 | union { | 
|---|
| .. | .. | 
|---|
| 196 | 199 | } | 
|---|
| 197 | 200 |  | 
|---|
| 198 | 201 | if (texp != 0) { | 
|---|
|  | 202 | +		if (flags & TFD_TIMER_ABSTIME) | 
|---|
|  | 203 | +			texp = timens_ktime_to_host(clockid, texp); | 
|---|
| 199 | 204 | if (isalarm(ctx)) { | 
|---|
| 200 | 205 | if (flags & TFD_TIMER_ABSTIME) | 
|---|
| 201 | 206 | alarm_start(&ctx->t.alarm, texp); | 
|---|
| .. | .. | 
|---|
| 302 | 307 | static void timerfd_show(struct seq_file *m, struct file *file) | 
|---|
| 303 | 308 | { | 
|---|
| 304 | 309 | struct timerfd_ctx *ctx = file->private_data; | 
|---|
| 305 |  | -	struct itimerspec t; | 
|---|
|  | 310 | +	struct timespec64 value, interval; | 
|---|
| 306 | 311 |  | 
|---|
| 307 | 312 | spin_lock_irq(&ctx->wqh.lock); | 
|---|
| 308 |  | -	t.it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); | 
|---|
| 309 |  | -	t.it_interval = ktime_to_timespec(ctx->tintv); | 
|---|
|  | 313 | +	value = ktime_to_timespec64(timerfd_get_remaining(ctx)); | 
|---|
|  | 314 | +	interval = ktime_to_timespec64(ctx->tintv); | 
|---|
| 310 | 315 | spin_unlock_irq(&ctx->wqh.lock); | 
|---|
| 311 | 316 |  | 
|---|
| 312 | 317 | seq_printf(m, | 
|---|
| .. | .. | 
|---|
| 318 | 323 | ctx->clockid, | 
|---|
| 319 | 324 | (unsigned long long)ctx->ticks, | 
|---|
| 320 | 325 | ctx->settime_flags, | 
|---|
| 321 |  | -		   (unsigned long long)t.it_value.tv_sec, | 
|---|
| 322 |  | -		   (unsigned long long)t.it_value.tv_nsec, | 
|---|
| 323 |  | -		   (unsigned long long)t.it_interval.tv_sec, | 
|---|
| 324 |  | -		   (unsigned long long)t.it_interval.tv_nsec); | 
|---|
|  | 326 | +		   (unsigned long long)value.tv_sec, | 
|---|
|  | 327 | +		   (unsigned long long)value.tv_nsec, | 
|---|
|  | 328 | +		   (unsigned long long)interval.tv_sec, | 
|---|
|  | 329 | +		   (unsigned long long)interval.tv_nsec); | 
|---|
| 325 | 330 | } | 
|---|
| 326 | 331 | #else | 
|---|
| 327 | 332 | #define timerfd_show NULL | 
|---|
| .. | .. | 
|---|
| 388 | 393 | { | 
|---|
| 389 | 394 | int ufd; | 
|---|
| 390 | 395 | struct timerfd_ctx *ctx; | 
|---|
|  | 396 | +	char file_name_buf[32]; | 
|---|
| 391 | 397 |  | 
|---|
| 392 | 398 | /* Check the TFD_* constants for consistency.  */ | 
|---|
| 393 | 399 | BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC); | 
|---|
| .. | .. | 
|---|
| 424 | 430 |  | 
|---|
| 425 | 431 | ctx->moffs = ktime_mono_to_real(0); | 
|---|
| 426 | 432 |  | 
|---|
| 427 |  | -	ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx, | 
|---|
|  | 433 | +	strlcpy(file_name_buf, "[timerfd]", sizeof(file_name_buf)); | 
|---|
|  | 434 | +	trace_android_vh_timerfd_create(file_name_buf, sizeof(file_name_buf)); | 
|---|
|  | 435 | +	ufd = anon_inode_getfd(file_name_buf, &timerfd_fops, ctx, | 
|---|
| 428 | 436 | O_RDWR | (flags & TFD_SHARED_FCNTL_FLAGS)); | 
|---|
| 429 | 437 | if (ufd < 0) | 
|---|
| 430 | 438 | kfree(ctx); | 
|---|
| .. | .. | 
|---|
| 432 | 440 | return ufd; | 
|---|
| 433 | 441 | } | 
|---|
| 434 | 442 |  | 
|---|
| 435 |  | -static int do_timerfd_settime(int ufd, int flags,  | 
|---|
|  | 443 | +static int do_timerfd_settime(int ufd, int flags, | 
|---|
| 436 | 444 | const struct itimerspec64 *new, | 
|---|
| 437 | 445 | struct itimerspec64 *old) | 
|---|
| 438 | 446 | { | 
|---|
| .. | .. | 
|---|
| 473 | 481 | spin_unlock_irq(&ctx->wqh.lock); | 
|---|
| 474 | 482 |  | 
|---|
| 475 | 483 | if (isalarm(ctx)) | 
|---|
| 476 |  | -			hrtimer_grab_expiry_lock(&ctx->t.alarm.timer); | 
|---|
|  | 484 | +			hrtimer_cancel_wait_running(&ctx->t.alarm.timer); | 
|---|
| 477 | 485 | else | 
|---|
| 478 |  | -			hrtimer_grab_expiry_lock(&ctx->t.tmr); | 
|---|
|  | 486 | +			hrtimer_cancel_wait_running(&ctx->t.tmr); | 
|---|
| 479 | 487 | } | 
|---|
| 480 | 488 |  | 
|---|
| 481 | 489 | /* | 
|---|
| .. | .. | 
|---|
| 564 | 572 | } | 
|---|
| 565 | 573 |  | 
|---|
| 566 | 574 | #ifdef CONFIG_COMPAT_32BIT_TIME | 
|---|
| 567 |  | -COMPAT_SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | 
|---|
| 568 |  | -		const struct compat_itimerspec __user *, utmr, | 
|---|
| 569 |  | -		struct compat_itimerspec __user *, otmr) | 
|---|
|  | 575 | +SYSCALL_DEFINE4(timerfd_settime32, int, ufd, int, flags, | 
|---|
|  | 576 | +		const struct old_itimerspec32 __user *, utmr, | 
|---|
|  | 577 | +		struct old_itimerspec32 __user *, otmr) | 
|---|
| 570 | 578 | { | 
|---|
| 571 | 579 | struct itimerspec64 new, old; | 
|---|
| 572 | 580 | int ret; | 
|---|
| 573 | 581 |  | 
|---|
| 574 |  | -	if (get_compat_itimerspec64(&new, utmr)) | 
|---|
|  | 582 | +	if (get_old_itimerspec32(&new, utmr)) | 
|---|
| 575 | 583 | return -EFAULT; | 
|---|
| 576 | 584 | ret = do_timerfd_settime(ufd, flags, &new, &old); | 
|---|
| 577 | 585 | if (ret) | 
|---|
| 578 | 586 | return ret; | 
|---|
| 579 |  | -	if (otmr && put_compat_itimerspec64(&old, otmr)) | 
|---|
|  | 587 | +	if (otmr && put_old_itimerspec32(&old, otmr)) | 
|---|
| 580 | 588 | return -EFAULT; | 
|---|
| 581 | 589 | return ret; | 
|---|
| 582 | 590 | } | 
|---|
| 583 | 591 |  | 
|---|
| 584 |  | -COMPAT_SYSCALL_DEFINE2(timerfd_gettime, int, ufd, | 
|---|
| 585 |  | -		struct compat_itimerspec __user *, otmr) | 
|---|
|  | 592 | +SYSCALL_DEFINE2(timerfd_gettime32, int, ufd, | 
|---|
|  | 593 | +		struct old_itimerspec32 __user *, otmr) | 
|---|
| 586 | 594 | { | 
|---|
| 587 | 595 | struct itimerspec64 kotmr; | 
|---|
| 588 | 596 | int ret = do_timerfd_gettime(ufd, &kotmr); | 
|---|
| 589 | 597 | if (ret) | 
|---|
| 590 | 598 | return ret; | 
|---|
| 591 |  | -	return put_compat_itimerspec64(&kotmr, otmr) ? -EFAULT : 0; | 
|---|
|  | 599 | +	return put_old_itimerspec32(&kotmr, otmr) ? -EFAULT : 0; | 
|---|
| 592 | 600 | } | 
|---|
| 593 | 601 | #endif | 
|---|