--- ../origins/kern/kern_time.c Fri Jul 14 15:37:47 2006 +++ kern/kern_time.c Fri Jul 14 15:37:47 2006 @@ -41,9 +41,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -104,6 +106,12 @@ SYSINIT(posix_timer, SI_SUB_P1003_1B, SI_ORDER_FIRST+4, itimer_start, NULL); +static int cf_usersettime; +static int cf_jailsettime; +SYSCTL_INT(_kern, OID_AUTO, usersettime, CTLFLAG_RW, &cf_usersettime, 0, + "Non-root is allowed to change system time"); +SYSCTL_INT(_kern, OID_AUTO, jailsettime, CTLFLAG_RW, &cf_jailsettime, 0, + "System time is allowed to be changed from jail"); static void no_lease_updatetime(deltat) @@ -265,8 +273,10 @@ if (error) return (error); #endif - if ((error = suser(td)) != 0) - return (error); + if (!cf_jailsettime && jailed(td->td_ucred)) + return (EPERM); + if (!cf_usersettime && (error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL)) != 0) + return (error); /* jail is already checked */ if (clock_id != CLOCK_REALTIME) return (EINVAL); if (ats->tv_nsec < 0 || ats->tv_nsec >= 1000000000) @@ -472,9 +482,12 @@ if (error) return (error); #endif - error = suser(td); - if (error) - return (error); + if (!cf_jailsettime && jailed(td->td_ucred)) + return (EPERM); + if (!cf_usersettime && (error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL)) != 0) + return (error); /* jail is already checked */ + else + error = 0; /* Verify all parameters before changing time. */ if (tv) { if (tv->tv_usec < 0 || tv->tv_usec >= 1000000) --- ../origins/kern/kern_ntptime.c Fri Jul 14 15:37:47 2006 +++ kern/kern_ntptime.c Fri Jul 14 15:37:47 2006 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -198,6 +199,13 @@ static void hardupdate(long offset); static void ntp_gettime1(struct ntptimeval *ntvp); +static int cf_useradjtime; +static int cf_jailadjtime; +SYSCTL_INT(_kern, OID_AUTO, useradjtime, CTLFLAG_RW, &cf_useradjtime, 0, + "Non-root is allowed to adjust system time"); +SYSCTL_INT(_kern, OID_AUTO, jailadjtime, CTLFLAG_RW, &cf_jailadjtime, 0, + "System time is allowed to be adjusted from jail"); + static void ntp_gettime1(struct ntptimeval *ntvp) { @@ -330,12 +338,20 @@ * the STA_PLL bit in the status word is cleared, the state and * status words are reset to the initial values at boot. */ - mtx_lock(&Giant); modes = ntv.modes; - if (modes) - error = suser(td); - if (error) - goto done2; + if (modes) { +#ifdef MAC + error = mac_check_system_settime(td->td_ucred); + if (error) + return (error); +#endif + if (!cf_jailadjtime && jailed(td->td_ucred)) + return (EPERM); + if (!cf_useradjtime && + (error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL)) != 0) + return (error); /* jail is already checked at this point */ + } + mtx_lock(&Giant); s = splclock(); if (modes & MOD_MAXERROR) time_maxerror = ntv.maxerror; @@ -954,8 +970,17 @@ struct timeval atv; int error; - if ((error = suser(td))) +#ifdef MAC + error = mac_check_system_settime(td->td_ucred); + if (error) return (error); +#endif + if (!cf_jailadjtime && jailed(td->td_ucred)) + return (EPERM); + if (!cf_useradjtime && (error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL)) != 0) + return (error); /* jail is already checked */ + else + error = 0; mtx_lock(&Giant); if (olddelta) {