• P
    locks: Fix potential OOPS in generic_setlease() · 85c59580
    Pavel Emelyanov 提交于
    This code is run under lock_kernel(), which is dropped during
    sleeping operations, so the following race is possible:
    
    CPU1:                                CPU2:
      vfs_setlease();                    vfs_setlease();
      lock_kernel();
                                         lock_kernel(); /* spin */
      generic_setlease():
        ...
        for (before = ...)
        /* here we found some lease after
         * which we will insert the new one
         */
        fl = locks_alloc_lock();
        /* go to sleep in this allocation and
         * drop the BKL
         */
                                         generic_setlease():
                                           ...
                                           for (before = ...)
                                           /* here we find the "before" pointing
                                            * at the one we found on CPU1
                                            */
                                          ->fl_change(my_before, arg);
                                                  lease_modify();
                                                         locks_free_lock();
                                                         /* and we freed it */
                                         ...
                                         unlock_kernel();
       locks_insert_lock(before, fl);
       /* OOPS! We have just tried to add the lease
        * at the tail of already removed one
        */
    
    The similar races are already handled in other code - all the
    allocations are performed before any checks/updates.
    
    Thanks to Kamalesh Babulal for testing and for a bug report on an
    earlier version.
    Signed-off-by: NPavel Emelyanov <xemul@openvz.org>
    Signed-off-by: NJ. Bruce Fields <bfields@citi.umich.edu>
    Cc: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
    85c59580
locks.c 57.6 KB