Feature #7510
closedenable highres clock usage for non-privileged users
100%
Description
Many applications on other systems allow non-privileged users to leverage the high resolution clock for timers. This has traditionally been behind a privilege as we worry about it being a potential way a user can create a denial of service.
We seem to have converged on the idea that without the priv we'll clamp the minimum monotonic value at something like 5000 hz (200 usecs) and if you have the priv you can do any interval. Once we're above a certain resolution (e.g., 1000 hz), we can also clamp you to evenly divide the interval.
Updated by Robert Mustacchi almost 2 years ago
To test this, I wrote a small program with a high-resolution timer that created a 23 nanosecond timer and then used DTrace to see if we had rewritten the timer interval. Here's the C program:
#include <stdio.h> #include <signal.h> #include <time.h> #include <err.h> #include <unistd.h> #include <strings.h> int main(void) { timer_t t; struct itimerspec it; if (timer_create(CLOCK_HIGHRES, NULL, &t) != 0) { err(1, "failed to create high res clock"); } bzero(&it, sizeof (it)); it.it_value.tv_nsec = 23; if (timer_settime(t, 0, &it, NULL) != 0) { err(1, "failed to create the timer"); } (void) pause(); return (0); }
Then, I used the following DTrace (long) one liner: dtrace -n 'fbt::clock_highres_timer_settime:entry/execname == "timer"/{ self->t = 1; print(*args[2]); }' -n 'fbt::ts2hrt:entry/self->t/{ print(*args[0]); }' -n 'fbt::clock_highres_timer_settime:return{ self->t = 0; }' -n 'fbt::cyclic_add:entry/self->t/{ print(*args[1]); }'
Running this, with the program as a normal user, you see:
root@beowulf:~# dtrace -n 'fbt::clock_highres_timer_settime:entry/execname == "timer"/{ self->t = 1; print(*args[2]); }' -n 'fbt::ts2hrt:entry/self->t/{ print(*args[0]); }' -n 'fbt::clock_highres_timer_settime:return{ self->t = 0; }' -n 'fbt::cyclic_add:entry/self->t/{ print(*args[1]); }' dtrace: description 'fbt::clock_highres_timer_settime:entry' matched 1 probe dtrace: description 'fbt::ts2hrt:entry' matched 1 probe dtrace: description 'fbt::clock_highres_timer_settime:return' matched 1 probe dtrace: description 'fbt::cyclic_add:entry' matched 1 probe CPU ID FUNCTION:NAME 30 10513 clock_highres_timer_settime:entry struct itimerspec { struct timespec it_interval = { time_t tv_sec = 0 long tv_nsec = 0 } struct timespec it_value = { time_t tv_sec = 0 long tv_nsec = 0x17 } } 30 20263 ts2hrt:entry timestruc_t { time_t tv_sec = 0 long tv_nsec = 0x30d40 } 30 20263 ts2hrt:entry timestruc_t { time_t tv_sec = 0 long tv_nsec = 0 } 30 17297 cyclic_add:entry cyc_time_t { hrtime_t cyt_when = 0x10230619721 hrtime_t cyt_interval = 0x7fffffffffffffff }
The second print statement is when we go through and have adjusted things. See how the 0x17 (23) was changed to 0x30d40 (200 us). If we now look at the output while running with root privileges:
^[[Aroot@beowulf:~# dtrace -n 'fbt::clock_highres_timer_settime:entry/execname == "timer"/{ self->t = 1; print(*args[2]); }' -n 'fbt::ts2hrt:entry/self->t/{ print(*args[0]); }' -n 'fbt::clock_highres_timer_settime:return{ self->t = 0; }' -n 'fbt::cyclic_add:entry/self->t/{ print(*args[1]); }' dtrace: description 'fbt::clock_highres_timer_settime:entry' matched 1 probe dtrace: description 'fbt::ts2hrt:entry' matched 1 probe dtrace: description 'fbt::clock_highres_timer_settime:return' matched 1 probe dtrace: description 'fbt::cyclic_add:entry' matched 1 probe CPU ID FUNCTION:NAME 23 10513 clock_highres_timer_settime:entry struct itimerspec { struct timespec it_interval = { time_t tv_sec = 0 long tv_nsec = 0 } struct timespec it_value = { time_t tv_sec = 0 long tv_nsec = 0x17 } } 23 20263 ts2hrt:entry timestruc_t { time_t tv_sec = 0 long tv_nsec = 0x17 } 23 20263 ts2hrt:entry timestruc_t { time_t tv_sec = 0 long tv_nsec = 0 } 23 17297 cyclic_add:entry cyc_time_t { hrtime_t cyt_when = 0x1294d5b1670 hrtime_t cyt_interval = 0x7fffffffffffffff }
In this case we've no longer adjusted this. So this proves that clamping does work correctly, doesn't interfere with root privileges, and provides a non-privileged user access to this with a reasonable granularity.
Updated by Robert Mustacchi almost 2 years ago
- Subject changed from enable highres clock usage for non-priviliged users to enable highres clock usage for non-privileged users
Updated by Electric Monk almost 2 years ago
- Status changed from New to Closed
git commit 605d010da59abaf92279a7caed83515cbb3218dc
commit 605d010da59abaf92279a7caed83515cbb3218dc Author: Jerry Jelinek <jerry.jelinek@joyent.com> Date: 2020-06-02T14:02:29.000Z 7510 enable highres clock usage for non-privileged users Reviewed by: Bryan Cantrill <bryan@joyent.com> Reviewed by: Patrick Mooney <patrick.mooney@joyent.com> Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Yuri Pankov <ypankov@tintri.com> Approved by: Richard Lowe <richlowe@richlowe.net>