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