diff options
author | Anton Vorontsov <anton.vorontsov@linaro.org> | 2012-06-18 22:15:53 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-06-20 19:15:22 -0400 |
commit | 1e6a9e56252399ae8c143f2327b4bb8cd289c3d5 (patch) | |
tree | e4dfb2629ec406052214197f8610ec5fbb39c724 /fs/pstore | |
parent | beeb94321a7a6d493b4a06ff0cd771f09f41c35e (diff) |
pstore/ram_core: Better ECC size checking
- Instead of exploiting unsigned overflows (which doesn't work for all
sizes), use straightforward checking for ECC total size not exceeding
initial buffer size;
- Printing overflowed buffer_size is not informative. Instead, print
ecc_size and buffer_size;
- No need for buffer_size argument in persistent_ram_init_ecc(),
we can address prz->buffer_size directly.
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/pstore')
-rw-r--r-- | fs/pstore/ram_core.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index f62ebf2dfed7..a5a7b13d358c 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c | |||
@@ -171,12 +171,12 @@ static void persistent_ram_ecc_old(struct persistent_ram_zone *prz) | |||
171 | } | 171 | } |
172 | } | 172 | } |
173 | 173 | ||
174 | static int persistent_ram_init_ecc(struct persistent_ram_zone *prz, | 174 | static int persistent_ram_init_ecc(struct persistent_ram_zone *prz) |
175 | size_t buffer_size) | ||
176 | { | 175 | { |
177 | int numerr; | 176 | int numerr; |
178 | struct persistent_ram_buffer *buffer = prz->buffer; | 177 | struct persistent_ram_buffer *buffer = prz->buffer; |
179 | int ecc_blocks; | 178 | int ecc_blocks; |
179 | size_t ecc_total; | ||
180 | 180 | ||
181 | if (!prz->ecc) | 181 | if (!prz->ecc) |
182 | return 0; | 182 | return 0; |
@@ -187,14 +187,14 @@ static int persistent_ram_init_ecc(struct persistent_ram_zone *prz, | |||
187 | prz->ecc_poly = 0x11d; | 187 | prz->ecc_poly = 0x11d; |
188 | 188 | ||
189 | ecc_blocks = DIV_ROUND_UP(prz->buffer_size, prz->ecc_block_size); | 189 | ecc_blocks = DIV_ROUND_UP(prz->buffer_size, prz->ecc_block_size); |
190 | prz->buffer_size -= (ecc_blocks + 1) * prz->ecc_size; | 190 | ecc_total = (ecc_blocks + 1) * prz->ecc_size; |
191 | 191 | if (ecc_total >= prz->buffer_size) { | |
192 | if (prz->buffer_size > buffer_size) { | 192 | pr_err("%s: invalid ecc_size %u (total %zu, buffer size %zu)\n", |
193 | pr_err("persistent_ram: invalid size %zu, non-ecc datasize %zu\n", | 193 | __func__, prz->ecc_size, ecc_total, prz->buffer_size); |
194 | buffer_size, prz->buffer_size); | ||
195 | return -EINVAL; | 194 | return -EINVAL; |
196 | } | 195 | } |
197 | 196 | ||
197 | prz->buffer_size -= ecc_total; | ||
198 | prz->par_buffer = buffer->data + prz->buffer_size; | 198 | prz->par_buffer = buffer->data + prz->buffer_size; |
199 | prz->par_header = prz->par_buffer + ecc_blocks * prz->ecc_size; | 199 | prz->par_header = prz->par_buffer + ecc_blocks * prz->ecc_size; |
200 | 200 | ||
@@ -397,7 +397,7 @@ static int __devinit persistent_ram_post_init(struct persistent_ram_zone *prz, | |||
397 | 397 | ||
398 | prz->ecc = ecc; | 398 | prz->ecc = ecc; |
399 | 399 | ||
400 | ret = persistent_ram_init_ecc(prz, prz->buffer_size); | 400 | ret = persistent_ram_init_ecc(prz); |
401 | if (ret) | 401 | if (ret) |
402 | return ret; | 402 | return ret; |
403 | 403 | ||