git: kernel: Allow fhold() in allfiles_scan_exclusive()
Sepherosa Ziehau
sephe at crater.dragonflybsd.org
Fri Sep 25 19:15:15 PDT 2015
commit d0505a2a9878750f03aa91af3f422e09b685d5e9
Author: Sepherosa Ziehau <sephe at dragonflybsd.org>
Date: Wed Sep 23 20:26:38 2015 +0800
kernel: Allow fhold() in allfiles_scan_exclusive()
Before this commit following race could happen, if fhold() is used
during allfiles_scan_exclusive():
Thread1 Thread2
: :
: fdrop(fp)
: {
Scan all fps if (f_count-- == 1) {
(*) fhold(fp) [f_count++] :
: fo_close(fp);
Access fp Unlink fp from filehead;
fdrop(fp) free(fp);
: }
: }
This could cause use-after-free or double free (since f_count == 1
when fdrop() was called in Thread1, fp will be freed again).
We now handle f_count 1->0 transition specially: hold the filehead
spin lock then do the f_count 1->0 transition, if the f_count 1->0
transition succeeds, the fp is unlinked from the filehead. This
prevents the above race from happening. This solution is mainly
based on dillon@'s input.
Summary of changes:
sys/kern/kern_descrip.c | 51 ++++++++++++++++++++++++++++++++++++-------------
1 file changed, 38 insertions(+), 13 deletions(-)
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/d0505a2a9878750f03aa91af3f422e09b685d5e9
--
DragonFly BSD source repository
More information about the Commits
mailing list