Skip to content
  • Sahitya Tummala's avatar
    jbd2: fix use after free in kjournald2() · cff3a5f2
    Sahitya Tummala authored
    commit dbfcef6b
    
     upstream.
    
    Below is the synchronization issue between unmount and kjournald2
    contexts, which results into use after free issue in kjournald2().
    Fix this issue by using journal->j_state_lock to synchronize the
    wait_event() done in journal_kill_thread() and the wake_up() done
    in kjournald2().
    
    TASK 1:
    umount cmd:
       |--jbd2_journal_destroy() {
           |--journal_kill_thread() {
                write_lock(&journal->j_state_lock);
    	    journal->j_flags |= JBD2_UNMOUNT;
    	    ...
    	    write_unlock(&journal->j_state_lock);
    	    wake_up(&journal->j_wait_commit);	   TASK 2 wakes up here:
    	    					   kjournald2() {
    						     ...
    						     checks JBD2_UNMOUNT flag and calls goto end-loop;
    						     ...
    						     end_loop:
    						       write_unlock(&journal->j_state_lock);
    						       journal->j_task = NULL; --> If this thread gets
    						       pre-empted here, then TASK 1 wait_event will
    						       exit even before this thread is completely
    						       done.
    	    wait_event(journal->j_wait_done_commit, journal->j_task == NULL);
    	    ...
    	    write_lock(&journal->j_state_lock);
    	    write_unlock(&journal->j_state_lock);
    	  }
           |--kfree(journal);
         }
    }
    						       wake_up(&journal->j_wait_done_commit); --> this step
    						       now results into use after free issue.
    						   }
    
    Signed-off-by: default avatarSahitya Tummala <stummala@codeaurora.org>
    Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
    Cc: Amit Pundir <amit.pundir@linaro.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    cff3a5f2