]>
Commit | Line | Data |
---|---|---|
b77986f5 GKH |
1 | From 8d5a803c6a6ce4ec258e31f76059ea5153ba46ef Mon Sep 17 00:00:00 2001 |
2 | From: Theodore Ts'o <tytso@mit.edu> | |
3 | Date: Thu, 12 Jul 2018 19:08:05 -0400 | |
4 | Subject: ext4: check for allocation block validity with block group locked | |
5 | ||
6 | From: Theodore Ts'o <tytso@mit.edu> | |
7 | ||
8 | commit 8d5a803c6a6ce4ec258e31f76059ea5153ba46ef upstream. | |
9 | ||
10 | With commit 044e6e3d74a3: "ext4: don't update checksum of new | |
11 | initialized bitmaps" the buffer valid bit will get set without | |
12 | actually setting up the checksum for the allocation bitmap, since the | |
13 | checksum will get calculated once we actually allocate an inode or | |
14 | block. | |
15 | ||
16 | If we are doing this, then we need to (re-)check the verified bit | |
17 | after we take the block group lock. Otherwise, we could race with | |
18 | another process reading and verifying the bitmap, which would then | |
19 | complain about the checksum being invalid. | |
20 | ||
21 | https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1780137 | |
22 | ||
23 | Signed-off-by: Theodore Ts'o <tytso@mit.edu> | |
24 | Cc: stable@kernel.org | |
25 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
26 | ||
27 | --- | |
28 | fs/ext4/balloc.c | 3 +++ | |
29 | fs/ext4/ialloc.c | 3 +++ | |
30 | 2 files changed, 6 insertions(+) | |
31 | ||
32 | --- a/fs/ext4/balloc.c | |
33 | +++ b/fs/ext4/balloc.c | |
34 | @@ -379,6 +379,8 @@ static int ext4_validate_block_bitmap(st | |
35 | return -EFSCORRUPTED; | |
36 | ||
37 | ext4_lock_group(sb, block_group); | |
38 | + if (buffer_verified(bh)) | |
39 | + goto verified; | |
40 | if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group, | |
41 | desc, bh))) { | |
42 | ext4_unlock_group(sb, block_group); | |
43 | @@ -401,6 +403,7 @@ static int ext4_validate_block_bitmap(st | |
44 | return -EFSCORRUPTED; | |
45 | } | |
46 | set_buffer_verified(bh); | |
47 | +verified: | |
48 | ext4_unlock_group(sb, block_group); | |
49 | return 0; | |
50 | } | |
51 | --- a/fs/ext4/ialloc.c | |
52 | +++ b/fs/ext4/ialloc.c | |
53 | @@ -91,6 +91,8 @@ static int ext4_validate_inode_bitmap(st | |
54 | return -EFSCORRUPTED; | |
55 | ||
56 | ext4_lock_group(sb, block_group); | |
57 | + if (buffer_verified(bh)) | |
58 | + goto verified; | |
59 | blk = ext4_inode_bitmap(sb, desc); | |
60 | if (!ext4_inode_bitmap_csum_verify(sb, block_group, desc, bh, | |
61 | EXT4_INODES_PER_GROUP(sb) / 8)) { | |
62 | @@ -108,6 +110,7 @@ static int ext4_validate_inode_bitmap(st | |
63 | return -EFSBADCRC; | |
64 | } | |
65 | set_buffer_verified(bh); | |
66 | +verified: | |
67 | ext4_unlock_group(sb, block_group); | |
68 | return 0; | |
69 | } |