diff options
author | cheloha <cheloha@cvs.openbsd.org> | 2020-10-07 15:45:01 +0000 |
---|---|---|
committer | cheloha <cheloha@cvs.openbsd.org> | 2020-10-07 15:45:01 +0000 |
commit | d318079e92389fab578f515008d3a03febb5955b (patch) | |
tree | f43e0d016e8f03d6ccd18788adc6797172661a34 /usr.sbin/slowcgi | |
parent | 058cf627e1faf59592c5b5c6f91528676d535f23 (diff) |
getitimer(2), setitimer(2): merge critical sections
Merge the common code from sys_getitimer() and sys_setitimer() into a
new kernel subroutine, setitimer(). setitimer() performs all of the
error-free work for both system calls within a single critical
section. We need a single critical section to make the setitimer(2)
timer swap operation atomic relative to realitexpire() and hardclock(9).
The downside of the new atomicity is that the behavior of setitimer(2)
must change. With a single critical section we can no longer copyout(9)
the old timer before installing the new timer. So If SCARG(uap, oitv)
points to invalid memory, setitimer(2) now fail with EFAULT but the
new timer will be left running. You can see this in action with code
like the following:
struct itv, olditv;
itv.it_value.tv_sec = 1;
itv.it_value.tv_usec = 0;
itv.it_interval = itv.it_value;
/* This should EFAULT. 0x1 is probably an invalid address. */
if (setitimer(ITIMER_REAL, &itv, (void *)0x1) == -1)
warn("setitimer");
/* The timer will be running anyway. */
getitimer(ITIMER_REAL, &olditv);
printf("time left: %lld.%06ld\n",
olditv.it_value.tv_sec, olditv.it_value.tv_usec);
There is no easy way to work around this. Both FreeBSD's and Linux's
setitimer(2) implementations have a single critical section and they
too fail with EFAULT in this case and leave the new timer running.
I imagine their developers decided that fixing this error case was
a waste of effort. Without permitting copyout(9) from within a mutex
I'm not sure it is even possible to avoid it on OpenBSD without
sacrificing atomicity during a setitimer(2) timer swap.
Given the rarity of this error case I would rather have an atomic swap.
Behavior change discussed with deraadt@.
Diffstat (limited to 'usr.sbin/slowcgi')
0 files changed, 0 insertions, 0 deletions