1/* 2 * Copyright (c) 2000-2007 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ 29/* 30 * Copyright (c) 1982, 1986, 1989, 1993 31 * The Regents of the University of California. All rights reserved. 32 * 33 * Redistribution and use in source and binary forms, with or without 34 * modification, are permitted provided that the following conditions 35 * are met: 36 * 1. Redistributions of source code must retain the above copyright 37 * notice, this list of conditions and the following disclaimer. 38 * 2. Redistributions in binary form must reproduce the above copyright 39 * notice, this list of conditions and the following disclaimer in the 40 * documentation and/or other materials provided with the distribution. 41 * 3. All advertising materials mentioning features or use of this software 42 * must display the following acknowledgement: 43 * This product includes software developed by the University of 44 * California, Berkeley and its contributors. 45 * 4. Neither the name of the University nor the names of its contributors 46 * may be used to endorse or promote products derived from this software 47 * without specific prior written permission. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 * SUCH DAMAGE. 60 * 61 * @(#)kern_time.c 8.4 (Berkeley) 5/26/95 62 */ 63/* 64 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce 65 * support for mandatory and extensible security protections. This notice 66 * is included in support of clause 2.2 (b) of the Apple Public License, 67 * Version 2.0. 68 */ 69 70#include <sys/param.h> 71#include <sys/resourcevar.h> 72#include <sys/kernel.h> 73#include <sys/systm.h> 74#include <sys/proc_internal.h> 75#include <sys/kauth.h> 76#include <sys/vnode.h> 77 78#include <sys/mount_internal.h> 79#include <sys/sysproto.h> 80#include <sys/signalvar.h> 81 82#include <kern/clock.h> 83#include <kern/task.h> 84#include <kern/thread_call.h> 85#if CONFIG_MACF 86#include <security/mac_framework.h> 87#endif 88 89#define HZ 100 /* XXX */ 90 91/* simple lock used to access timezone, tz structure */ 92lck_spin_t * tz_slock; 93lck_grp_t * tz_slock_grp; 94lck_attr_t * tz_slock_attr; 95lck_grp_attr_t *tz_slock_grp_attr; 96 97static void setthetime( 98 struct timeval *tv); 99 100void time_zone_slock_init(void) __attribute__((section("__TEXT, initcode"))); 101 102/* 103 * Time of day and interval timer support. 104 * 105 * These routines provide the kernel entry points to get and set 106 * the time-of-day and per-process interval timers. Subroutines 107 * here provide support for adding and subtracting timeval structures 108 * and decrementing interval timers, optionally reloading the interval 109 * timers when they expire. 110 */ 111/* ARGSUSED */ 112int 113gettimeofday( 114__unused struct proc *p, 115 struct gettimeofday_args *uap, 116 register_t *retval) 117{ 118 int error = 0; 119 struct timezone ltz; /* local copy */ 120 121 if (uap->tp) 122 clock_gettimeofday((uint32_t *)&retval[0], (uint32_t *)&retval[1]); 123 124 if (uap->tzp) { 125 lck_spin_lock(tz_slock); 126 ltz = tz; 127 lck_spin_unlock(tz_slock); 128 129 error = copyout((caddr_t)<z, CAST_USER_ADDR_T(uap->tzp), sizeof (tz)); 130 } 131 132 return (error); 133} 134 135/* 136 * XXX Y2038 bug because of setthetime() argument 137 */ 138/* ARGSUSED */ 139int 140settimeofday(__unused struct proc *p, struct settimeofday_args *uap, __unused register_t *retval) 141{ 142 struct timeval atv; 143 struct timezone atz; 144 int error; 145 146#if CONFIG_MACF 147 error = mac_system_check_settime(kauth_cred_get()); 148 if (error) 149 return (error); 150#endif 151#ifndef CONFIG_EMBEDDED 152 if ((error = suser(kauth_cred_get(), &p->p_acflag))) 153 return (error); 154#endif 155 /* Verify all parameters before changing time */ 156 if (uap->tv) { 157 if (IS_64BIT_PROCESS(p)) { 158 struct user_timeval user_atv; 159 error = copyin(uap->tv, &user_atv, sizeof(struct user_timeval)); 160 atv.tv_sec = user_atv.tv_sec; 161 atv.tv_usec = user_atv.tv_usec; 162 } else { 163 error = copyin(uap->tv, &atv, sizeof(struct timeval)); 164 } 165 if (error) 166 return (error); 167 } 168 if (uap->tzp && (error = copyin(uap->tzp, (caddr_t)&atz, sizeof(atz)))) 169 return (error); 170 if (uap->tv) { 171 timevalfix(&atv); 172 if (atv.tv_sec < 0 || (atv.tv_sec == 0 && atv.tv_usec < 0)) 173 return (EPERM); 174 setthetime(&atv); 175 } 176 if (uap->tzp) { 177 lck_spin_lock(tz_slock); 178 tz = atz; 179 lck_spin_unlock(tz_slock); 180 } 181 return (0); 182} 183 184static void 185setthetime( 186 struct timeval *tv) 187{ 188 clock_set_calendar_microtime(tv->tv_sec, tv->tv_usec); 189} 190 191/* 192 * XXX Y2038 bug because of clock_adjtime() first argument 193 */ 194/* ARGSUSED */ 195int 196adjtime(struct proc *p, struct adjtime_args *uap, __unused register_t *retval) 197{ 198 struct timeval atv; 199 int error; 200 201#if CONFIG_MACF 202 error = mac_system_check_settime(kauth_cred_get()); 203 if (error) 204 return (error); 205#endif 206 if ((error = suser(kauth_cred_get(), &p->p_acflag))) 207 return (error); 208 if (IS_64BIT_PROCESS(p)) { 209 struct user_timeval user_atv; 210 error = copyin(uap->delta, &user_atv, sizeof(struct user_timeval)); 211 atv.tv_sec = user_atv.tv_sec; 212 atv.tv_usec = user_atv.tv_usec; 213 } else { 214 error = copyin(uap->delta, &atv, sizeof(struct timeval)); 215 } 216 if (error) 217 return (error); 218 219 /* 220 * Compute the total correction and the rate at which to apply it. 221 */ 222 clock_adjtime((int32_t *)&atv.tv_sec, &atv.tv_usec); 223 224 if (uap->olddelta) { 225 if (IS_64BIT_PROCESS(p)) { 226 struct user_timeval user_atv; 227 user_atv.tv_sec = atv.tv_sec; 228 user_atv.tv_usec = atv.tv_usec; 229 error = copyout(&user_atv, uap->olddelta, sizeof(struct user_timeval)); 230 } else { 231 error = copyout(&atv, uap->olddelta, sizeof(struct timeval)); 232 } 233 } 234 235 return (0); 236} 237 238/* 239 * Verify the calendar value. If negative, 240 * reset to zero (the epoch). 241 */ 242void 243inittodr( 244 __unused time_t base) 245{ 246 struct timeval tv; 247 248 /* 249 * Assertion: 250 * The calendar has already been 251 * set up from the platform clock. 252 * 253 * The value returned by microtime() 254 * is gotten from the calendar. 255 */ 256 microtime(&tv); 257 258 if (tv.tv_sec < 0 || tv.tv_usec < 0) { 259 printf ("WARNING: preposterous time in Real Time Clock"); 260 tv.tv_sec = 0; /* the UNIX epoch */ 261 tv.tv_usec = 0; 262 setthetime(&tv); 263 printf(" -- CHECK AND RESET THE DATE!\n"); 264 } 265} 266 267time_t 268boottime_sec(void) 269{ 270 uint32_t sec, nanosec; 271 clock_get_boottime_nanotime(&sec, &nanosec); 272 return (sec); 273} 274 275uint64_t tvtoabstime(struct timeval *tvp); 276 277/* 278 * Get value of an interval timer. The process virtual and 279 * profiling virtual time timers are kept internally in the 280 * way they are specified externally: in time until they expire. 281 * 282 * The real time interval timer expiration time (p_rtime) 283 * is kept as an absolute time rather than as a delta, so that 284 * it is easy to keep periodic real-time signals from drifting. 285 * 286 * The real time timer is processed by a callout routine. 287 * Since a callout may be delayed in real time due to 288 * other processing in the system, it is possible for the real 289 * time callout routine (realitexpire, given below), to be delayed 290 * in real time past when it is supposed to occur. It does not 291 * suffice, therefore, to reload the real time .it_value from the 292 * real time .it_interval. Rather, we compute the next time in 293 * absolute time when the timer should go off. 294 * 295 * Returns: 0 Success 296 * EINVAL Invalid argument 297 * copyout:EFAULT Bad address 298 */ 299/* ARGSUSED */ 300int 301getitimer(struct proc *p, struct getitimer_args *uap, __unused register_t *retval) 302{ 303 struct itimerval aitv; 304 305 if (uap->which > ITIMER_PROF) 306 return(EINVAL); 307 308 proc_spinlock(p); 309 switch (uap->which) { 310 311 case ITIMER_REAL: 312 /* 313 * If time for real time timer has passed return 0, 314 * else return difference between current time and 315 * time for the timer to go off. 316 */ 317 aitv = p->p_realtimer; 318 if (timerisset(&p->p_rtime)) { 319 struct timeval now; 320 321 microuptime(&now); 322 if (timercmp(&p->p_rtime, &now, <)) 323 timerclear(&aitv.it_value); 324 else { 325 aitv.it_value = p->p_rtime; 326 timevalsub(&aitv.it_value, &now); 327 } 328 } 329 else 330 timerclear(&aitv.it_value); 331 break; 332 333 case ITIMER_VIRTUAL: 334 aitv = p->p_vtimer_user; 335 break; 336 337 case ITIMER_PROF: 338 aitv = p->p_vtimer_prof; 339 break; 340 } 341 342 proc_spinunlock(p); 343 344 if (IS_64BIT_PROCESS(p)) { 345 struct user_itimerval user_itv; 346 user_itv.it_interval.tv_sec = aitv.it_interval.tv_sec; 347 user_itv.it_interval.tv_usec = aitv.it_interval.tv_usec; 348 user_itv.it_value.tv_sec = aitv.it_value.tv_sec; 349 user_itv.it_value.tv_usec = aitv.it_value.tv_usec; 350 return (copyout((caddr_t)&user_itv, uap->itv, sizeof (struct user_itimerval))); 351 } else { 352 return (copyout((caddr_t)&aitv, uap->itv, sizeof (struct itimerval))); 353 } 354} 355 356/* 357 * Returns: 0 Success 358 * EINVAL Invalid argument 359 * copyin:EFAULT Bad address 360 * getitimer:EINVAL Invalid argument 361 * getitimer:EFAULT Bad address 362 */ 363/* ARGSUSED */ 364int 365setitimer(struct proc *p, struct setitimer_args *uap, register_t *retval) 366{ 367 struct itimerval aitv; 368 user_addr_t itvp; 369 int error; 370 371 if (uap->which > ITIMER_PROF) 372 return (EINVAL); 373 if ((itvp = uap->itv)) { 374 if (IS_64BIT_PROCESS(p)) { 375 struct user_itimerval user_itv; 376 if ((error = copyin(itvp, (caddr_t)&user_itv, sizeof (struct user_itimerval)))) 377 return (error); 378 aitv.it_interval.tv_sec = user_itv.it_interval.tv_sec; 379 aitv.it_interval.tv_usec = user_itv.it_interval.tv_usec; 380 aitv.it_value.tv_sec = user_itv.it_value.tv_sec; 381 aitv.it_value.tv_usec = user_itv.it_value.tv_usec; 382 } else { 383 if ((error = copyin(itvp, (caddr_t)&aitv, sizeof (struct itimerval)))) 384 return (error); 385 } 386 } 387 if ((uap->itv = uap->oitv) && (error = getitimer(p, (struct getitimer_args *)uap, retval))) 388 return (error); 389 if (itvp == 0) 390 return (0); 391 if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval)) 392 return (EINVAL); 393 394 switch (uap->which) { 395 396 case ITIMER_REAL: 397 proc_spinlock(p); 398 if (timerisset(&aitv.it_value)) { 399 microuptime(&p->p_rtime); 400 timevaladd(&p->p_rtime, &aitv.it_value); 401 p->p_realtimer = aitv; 402 if (!thread_call_enter_delayed(p->p_rcall, tvtoabstime(&p->p_rtime))) 403 p->p_ractive++; 404 } else { 405 timerclear(&p->p_rtime); 406 p->p_realtimer = aitv; 407 if (thread_call_cancel(p->p_rcall)) 408 p->p_ractive--; 409 } 410 proc_spinunlock(p); 411 412 break; 413 414 415 case ITIMER_VIRTUAL: 416 if (timerisset(&aitv.it_value)) 417 task_vtimer_set(p->task, TASK_VTIMER_USER); 418 else 419 task_vtimer_clear(p->task, TASK_VTIMER_USER); 420 421 proc_spinlock(p); 422 p->p_vtimer_user = aitv; 423 proc_spinunlock(p); 424 break; 425 426 case ITIMER_PROF: 427 if (timerisset(&aitv.it_value)) 428 task_vtimer_set(p->task, TASK_VTIMER_PROF); 429 else 430 task_vtimer_clear(p->task, TASK_VTIMER_PROF); 431 432 proc_spinlock(p); 433 p->p_vtimer_prof = aitv; 434 proc_spinunlock(p); 435 break; 436 } 437 438 return (0); 439} 440 441/* 442 * Real interval timer expired: 443 * send process whose timer expired an alarm signal. 444 * If time is not set up to reload, then just return. 445 * Else compute next time timer should go off which is > current time. 446 * This is where delay in processing this timeout causes multiple 447 * SIGALRM calls to be compressed into one. 448 */ 449void 450realitexpire( 451 struct proc *p) 452{ 453 struct proc *r; 454 struct timeval t; 455 456 r = proc_find(p->p_pid); 457 458 proc_spinlock(p); 459 460 if (--p->p_ractive > 0 || r != p) { 461 proc_spinunlock(p); 462 463 if (r != NULL) 464 proc_rele(r); 465 return; 466 } 467 468 if (!timerisset(&p->p_realtimer.it_interval)) { 469 timerclear(&p->p_rtime); 470 proc_spinunlock(p); 471 472 psignal(p, SIGALRM); 473 proc_rele(p); 474 return; 475 } 476 477 microuptime(&t); 478 timevaladd(&p->p_rtime, &p->p_realtimer.it_interval); 479 if (timercmp(&p->p_rtime, &t, <=)) { 480 if ((p->p_rtime.tv_sec + 2) >= t.tv_sec) { 481 for (;;) { 482 timevaladd(&p->p_rtime, &p->p_realtimer.it_interval); 483 if (timercmp(&p->p_rtime, &t, >)) 484 break; 485 } 486 } 487 else { 488 p->p_rtime = p->p_realtimer.it_interval; 489 timevaladd(&p->p_rtime, &t); 490 } 491 } 492 493 if (!thread_call_enter_delayed(p->p_rcall, tvtoabstime(&p->p_rtime))) 494 p->p_ractive++; 495 proc_spinunlock(p); 496 497 psignal(p, SIGALRM); 498 proc_rele(p); 499} 500 501/* 502 * Check that a proposed value to load into the .it_value or 503 * .it_interval part of an interval timer is acceptable. 504 */ 505int 506itimerfix( 507 struct timeval *tv) 508{ 509 510 if (tv->tv_sec < 0 || tv->tv_sec > 100000000 || 511 tv->tv_usec < 0 || tv->tv_usec >= 1000000) 512 return (EINVAL); 513 return (0); 514} 515 516/* 517 * Decrement an interval timer by a specified number 518 * of microseconds, which must be less than a second, 519 * i.e. < 1000000. If the timer expires, then reload 520 * it. In this case, carry over (usec - old value) to 521 * reduce the value reloaded into the timer so that 522 * the timer does not drift. This routine assumes 523 * that it is called in a context where the timers 524 * on which it is operating cannot change in value. 525 */ 526int 527itimerdecr(proc_t p, 528 struct itimerval *itp, int usec) 529{ 530 531 proc_spinlock(p); 532 533 if (itp->it_value.tv_usec < usec) { 534 if (itp->it_value.tv_sec == 0) { 535 /* expired, and already in next interval */ 536 usec -= itp->it_value.tv_usec; 537 goto expire; 538 } 539 itp->it_value.tv_usec += 1000000; 540 itp->it_value.tv_sec--; 541 } 542 itp->it_value.tv_usec -= usec; 543 usec = 0; 544 if (timerisset(&itp->it_value)) { 545 proc_spinunlock(p); 546 return (1); 547 } 548 /* expired, exactly at end of interval */ 549expire: 550 if (timerisset(&itp->it_interval)) { 551 itp->it_value = itp->it_interval; 552 if (itp->it_value.tv_sec > 0) { 553 itp->it_value.tv_usec -= usec; 554 if (itp->it_value.tv_usec < 0) { 555 itp->it_value.tv_usec += 1000000; 556 itp->it_value.tv_sec--; 557 } 558 } 559 } else 560 itp->it_value.tv_usec = 0; /* sec is already 0 */ 561 proc_spinunlock(p); 562 return (0); 563} 564 565/* 566 * Add and subtract routines for timevals. 567 * N.B.: subtract routine doesn't deal with 568 * results which are before the beginning, 569 * it just gets very confused in this case. 570 * Caveat emptor. 571 */ 572void 573timevaladd( 574 struct timeval *t1, 575 struct timeval *t2) 576{ 577 578 t1->tv_sec += t2->tv_sec; 579 t1->tv_usec += t2->tv_usec; 580 timevalfix(t1); 581} 582void 583timevalsub( 584 struct timeval *t1, 585 struct timeval *t2) 586{ 587 588 t1->tv_sec -= t2->tv_sec; 589 t1->tv_usec -= t2->tv_usec; 590 timevalfix(t1); 591} 592void 593timevalfix( 594 struct timeval *t1) 595{ 596 597 if (t1->tv_usec < 0) { 598 t1->tv_sec--; 599 t1->tv_usec += 1000000; 600 } 601 if (t1->tv_usec >= 1000000) { 602 t1->tv_sec++; 603 t1->tv_usec -= 1000000; 604 } 605} 606 607/* 608 * Return the best possible estimate of the time in the timeval 609 * to which tvp points. 610 */ 611void 612microtime( 613 struct timeval *tvp) 614{ 615 clock_get_calendar_microtime((uint32_t *)&tvp->tv_sec, (uint32_t *)&tvp->tv_usec); 616} 617 618void 619microuptime( 620 struct timeval *tvp) 621{ 622 clock_get_system_microtime((uint32_t *)&tvp->tv_sec, (uint32_t *)&tvp->tv_usec); 623} 624 625/* 626 * Ditto for timespec. 627 */ 628void 629nanotime( 630 struct timespec *tsp) 631{ 632 clock_get_calendar_nanotime((uint32_t *)&tsp->tv_sec, (uint32_t *)&tsp->tv_nsec); 633} 634 635void 636nanouptime( 637 struct timespec *tsp) 638{ 639 clock_get_system_nanotime((uint32_t *)&tsp->tv_sec, (uint32_t *)&tsp->tv_nsec); 640} 641 642uint64_t 643tvtoabstime( 644 struct timeval *tvp) 645{ 646 uint64_t result, usresult; 647 648 clock_interval_to_absolutetime_interval( 649 tvp->tv_sec, NSEC_PER_SEC, &result); 650 clock_interval_to_absolutetime_interval( 651 tvp->tv_usec, NSEC_PER_USEC, &usresult); 652 653 return (result + usresult); 654} 655void 656time_zone_slock_init(void) 657{ 658 /* allocate lock group attribute and group */ 659 tz_slock_grp_attr = lck_grp_attr_alloc_init(); 660 661 tz_slock_grp = lck_grp_alloc_init("tzlock", tz_slock_grp_attr); 662 663 /* Allocate lock attribute */ 664 tz_slock_attr = lck_attr_alloc_init(); 665 666 /* Allocate the spin lock */ 667 tz_slock = lck_spin_alloc_init(tz_slock_grp, tz_slock_attr); 668} 669