ext4: fix possible use-after-free in ext4_remove_li_request()
authorLukas Czerner <lczerner@redhat.com>
Fri, 20 May 2011 17:55:29 +0000 (13:55 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 20 May 2011 17:55:29 +0000 (13:55 -0400)
We need to take reference to the s_li_request after we take a mutex,
because it might be freed since then, hence result in accessing old
already freed memory. Also we should protect the whole
ext4_remove_li_request() because ext4_li_info might be in the process of
being freed in ext4_lazyinit_thread().

Signed-off-by: Lukas Czerner <lczerner@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
fs/ext4/super.c

index fd51a4a266b65c8101567e480ed47f090c653e50..ed5e80ef48c46a6018203708ed3250fa64d2bffa 100644 (file)
@@ -2735,14 +2735,16 @@ static void ext4_remove_li_request(struct ext4_li_request *elr)
 
 static void ext4_unregister_li_request(struct super_block *sb)
 {
-       struct ext4_li_request *elr = EXT4_SB(sb)->s_li_request;
-
-       if (!ext4_li_info)
+       mutex_lock(&ext4_li_mtx);
+       if (!ext4_li_info) {
+               mutex_unlock(&ext4_li_mtx);
                return;
+       }
 
        mutex_lock(&ext4_li_info->li_list_mtx);
-       ext4_remove_li_request(elr);
+       ext4_remove_li_request(EXT4_SB(sb)->s_li_request);
        mutex_unlock(&ext4_li_info->li_list_mtx);
+       mutex_unlock(&ext4_li_mtx);
 }
 
 static struct task_struct *ext4_lazyinit_task;