Page MenuHomeFreeBSD

sem_post(): wake up the sleeper after adjusting has_waiters
ClosedPublic

Authored by badger on Aug 15 2016, 2:30 PM.

Details

Summary

If the caller of sem_post() wakes up a thread sleeping via sem_wait()
before it clears the has_waiters flag, the caller of sem_wait() has no way of
knowing when it is safe to destroy the semaphore and reuse the memory. This is
because the caller of sem_post() may be interrupted between the wake step and
the clearing of has_waiters. It will then write into the has_waiters flag in
userspace after being preempted for some unknown amount of time.

A test program that illustrates the issue I want to fix is here:
https://people.freebsd.org/~badger/tests/sem_post-stack-corrupt/semaphore.c .
This program can sometimes exit in the otherfunc() function printing
"sem struct changed after yielding". There is a README.txt file in that
same directory describing the test in more detail.

Diff Detail

Repository
rS FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

badger updated this revision to Diff 19286.Aug 15 2016, 2:30 PM
badger retitled this revision from to Wake up the sleeper after adjusting has_waiters.
badger updated this object.
badger edited the test plan for this revision. (Show Details)
badger retitled this revision from Wake up the sleeper after adjusting has_waiters to sem_post(): wake up the sleeper after adjusting has_waiters.Aug 15 2016, 2:35 PM
badger updated this object.
badger added reviewers: vangyzen, kib.
vangyzen accepted this revision.Aug 15 2016, 2:56 PM
vangyzen edited edge metadata.
This revision is now accepted and ready to land.Aug 15 2016, 2:56 PM
badger added a reviewer: jhb.Aug 15 2016, 3:49 PM
kib accepted this revision.Aug 15 2016, 3:56 PM
kib edited edge metadata.
jhb accepted this revision.Aug 15 2016, 5:36 PM
jhb edited edge metadata.
This revision was automatically updated to reflect the committed changes.