]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.8.5/ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch
drop queue-4.14/mips-make-sure-dt-memory-regions-are-valid.patch
[thirdparty/kernel/stable-queue.git] / releases / 3.8.5 / ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch
CommitLineData
40f90573
GKH
1From 90ba983f6889e65a3b506b30dc606aa9d1d46cd2 Mon Sep 17 00:00:00 2001
2From: Theodore Ts'o <tytso@mit.edu>
3Date: Mon, 11 Mar 2013 23:39:59 -0400
4Subject: ext4: use atomic64_t for the per-flexbg free_clusters count
5
6From: Theodore Ts'o <tytso@mit.edu>
7
8commit 90ba983f6889e65a3b506b30dc606aa9d1d46cd2 upstream.
9
10A user who was using a 8TB+ file system and with a very large flexbg
11size (> 65536) could cause the atomic_t used in the struct flex_groups
12to overflow. This was detected by PaX security patchset:
13
14http://forums.grsecurity.net/viewtopic.php?f=3&t=3289&p=12551#p12551
15
16This bug was introduced in commit 9f24e4208f7e, so it's been around
17since 2.6.30. :-(
18
19Fix this by using an atomic64_t for struct orlav_stats's
20free_clusters.
21
22Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
23Reviewed-by: Lukas Czerner <lczerner@redhat.com>
24Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
25
26---
27 fs/ext4/ext4.h | 6 +++---
28 fs/ext4/ialloc.c | 4 ++--
29 fs/ext4/mballoc.c | 12 ++++++------
30 fs/ext4/resize.c | 4 ++--
31 fs/ext4/super.c | 4 ++--
32 5 files changed, 15 insertions(+), 15 deletions(-)
33
34--- a/fs/ext4/ext4.h
35+++ b/fs/ext4/ext4.h
36@@ -338,9 +338,9 @@ struct ext4_group_desc
37 */
38
39 struct flex_groups {
40- atomic_t free_inodes;
41- atomic_t free_clusters;
42- atomic_t used_dirs;
43+ atomic64_t free_clusters;
44+ atomic_t free_inodes;
45+ atomic_t used_dirs;
46 };
47
48 #define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */
49--- a/fs/ext4/ialloc.c
50+++ b/fs/ext4/ialloc.c
51@@ -324,8 +324,8 @@ error_return:
52 }
53
54 struct orlov_stats {
55+ __u64 free_clusters;
56 __u32 free_inodes;
57- __u32 free_clusters;
58 __u32 used_dirs;
59 };
60
61@@ -342,7 +342,7 @@ static void get_orlov_stats(struct super
62
63 if (flex_size > 1) {
64 stats->free_inodes = atomic_read(&flex_group[g].free_inodes);
65- stats->free_clusters = atomic_read(&flex_group[g].free_clusters);
66+ stats->free_clusters = atomic64_read(&flex_group[g].free_clusters);
67 stats->used_dirs = atomic_read(&flex_group[g].used_dirs);
68 return;
69 }
70--- a/fs/ext4/mballoc.c
71+++ b/fs/ext4/mballoc.c
72@@ -2829,8 +2829,8 @@ ext4_mb_mark_diskspace_used(struct ext4_
73 if (sbi->s_log_groups_per_flex) {
74 ext4_group_t flex_group = ext4_flex_group(sbi,
75 ac->ac_b_ex.fe_group);
76- atomic_sub(ac->ac_b_ex.fe_len,
77- &sbi->s_flex_groups[flex_group].free_clusters);
78+ atomic64_sub(ac->ac_b_ex.fe_len,
79+ &sbi->s_flex_groups[flex_group].free_clusters);
80 }
81
82 err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
83@@ -4691,8 +4691,8 @@ do_more:
84
85 if (sbi->s_log_groups_per_flex) {
86 ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
87- atomic_add(count_clusters,
88- &sbi->s_flex_groups[flex_group].free_clusters);
89+ atomic64_add(count_clusters,
90+ &sbi->s_flex_groups[flex_group].free_clusters);
91 }
92
93 ext4_mb_unload_buddy(&e4b);
94@@ -4836,8 +4836,8 @@ int ext4_group_add_blocks(handle_t *hand
95
96 if (sbi->s_log_groups_per_flex) {
97 ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
98- atomic_add(EXT4_NUM_B2C(sbi, blocks_freed),
99- &sbi->s_flex_groups[flex_group].free_clusters);
100+ atomic64_add(EXT4_NUM_B2C(sbi, blocks_freed),
101+ &sbi->s_flex_groups[flex_group].free_clusters);
102 }
103
104 ext4_mb_unload_buddy(&e4b);
105--- a/fs/ext4/resize.c
106+++ b/fs/ext4/resize.c
107@@ -1360,8 +1360,8 @@ static void ext4_update_super(struct sup
108 sbi->s_log_groups_per_flex) {
109 ext4_group_t flex_group;
110 flex_group = ext4_flex_group(sbi, group_data[0].group);
111- atomic_add(EXT4_NUM_B2C(sbi, free_blocks),
112- &sbi->s_flex_groups[flex_group].free_clusters);
113+ atomic64_add(EXT4_NUM_B2C(sbi, free_blocks),
114+ &sbi->s_flex_groups[flex_group].free_clusters);
115 atomic_add(EXT4_INODES_PER_GROUP(sb) * flex_gd->count,
116 &sbi->s_flex_groups[flex_group].free_inodes);
117 }
118--- a/fs/ext4/super.c
119+++ b/fs/ext4/super.c
120@@ -1979,8 +1979,8 @@ static int ext4_fill_flex_info(struct su
121 flex_group = ext4_flex_group(sbi, i);
122 atomic_add(ext4_free_inodes_count(sb, gdp),
123 &sbi->s_flex_groups[flex_group].free_inodes);
124- atomic_add(ext4_free_group_clusters(sb, gdp),
125- &sbi->s_flex_groups[flex_group].free_clusters);
126+ atomic64_add(ext4_free_group_clusters(sb, gdp),
127+ &sbi->s_flex_groups[flex_group].free_clusters);
128 atomic_add(ext4_used_dirs_count(sb, gdp),
129 &sbi->s_flex_groups[flex_group].used_dirs);
130 }