diff options
author | Arve Hjønnevåg <arve@android.com> | 2012-12-11 20:49:24 -0500 |
---|---|---|
committer | Anton Vorontsov <anton.vorontsov@linaro.org> | 2012-12-12 22:02:52 -0500 |
commit | c628937803c652132d21f383736375e2feee4bfb (patch) | |
tree | 41ebffb3fe0b787c34ba2c45f860336f5d27e0ca /fs/pstore/ram.c | |
parent | b042e47491ba5f487601b5141a3f1d8582304170 (diff) |
pstore/ram: Fix bounds checks for mem_size, record_size, console_size and ftrace_size
The bounds check in ramoops_init_prz was incorrect and ramoops_init_przs
had no check. Additionally, ramoops_init_przs allows record_size to be 0,
but ramoops_pstore_write_buf would always crash in this case.
Signed-off-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
Diffstat (limited to 'fs/pstore/ram.c')
-rw-r--r-- | fs/pstore/ram.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 8741cea6253c..dba70e53b72c 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c | |||
@@ -189,7 +189,7 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type, | |||
189 | struct pstore_info *psi) | 189 | struct pstore_info *psi) |
190 | { | 190 | { |
191 | struct ramoops_context *cxt = psi->data; | 191 | struct ramoops_context *cxt = psi->data; |
192 | struct persistent_ram_zone *prz = cxt->przs[cxt->dump_write_cnt]; | 192 | struct persistent_ram_zone *prz; |
193 | size_t hlen; | 193 | size_t hlen; |
194 | 194 | ||
195 | if (type == PSTORE_TYPE_CONSOLE) { | 195 | if (type == PSTORE_TYPE_CONSOLE) { |
@@ -226,6 +226,11 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type, | |||
226 | if (part != 1) | 226 | if (part != 1) |
227 | return -ENOSPC; | 227 | return -ENOSPC; |
228 | 228 | ||
229 | if (!cxt->przs) | ||
230 | return -ENOSPC; | ||
231 | |||
232 | prz = cxt->przs[cxt->dump_write_cnt]; | ||
233 | |||
229 | hlen = ramoops_write_kmsg_hdr(prz); | 234 | hlen = ramoops_write_kmsg_hdr(prz); |
230 | if (size + hlen > prz->buffer_size) | 235 | if (size + hlen > prz->buffer_size) |
231 | size = prz->buffer_size - hlen; | 236 | size = prz->buffer_size - hlen; |
@@ -297,6 +302,11 @@ static int __devinit ramoops_init_przs(struct device *dev, | |||
297 | if (!cxt->record_size) | 302 | if (!cxt->record_size) |
298 | return 0; | 303 | return 0; |
299 | 304 | ||
305 | if (*paddr + dump_mem_sz - cxt->phys_addr > cxt->size) { | ||
306 | dev_err(dev, "no room for dumps\n"); | ||
307 | return -ENOMEM; | ||
308 | } | ||
309 | |||
300 | cxt->max_dump_cnt = dump_mem_sz / cxt->record_size; | 310 | cxt->max_dump_cnt = dump_mem_sz / cxt->record_size; |
301 | if (!cxt->max_dump_cnt) | 311 | if (!cxt->max_dump_cnt) |
302 | return -ENOMEM; | 312 | return -ENOMEM; |
@@ -335,8 +345,12 @@ static int __devinit ramoops_init_prz(struct device *dev, | |||
335 | if (!sz) | 345 | if (!sz) |
336 | return 0; | 346 | return 0; |
337 | 347 | ||
338 | if (*paddr + sz > *paddr + cxt->size) | 348 | if (*paddr + sz - cxt->phys_addr > cxt->size) { |
349 | dev_err(dev, "no room for mem region (0x%zx@0x%llx) in (0x%lx@0x%llx)\n", | ||
350 | sz, (unsigned long long)*paddr, | ||
351 | cxt->size, (unsigned long long)cxt->phys_addr); | ||
339 | return -ENOMEM; | 352 | return -ENOMEM; |
353 | } | ||
340 | 354 | ||
341 | *prz = persistent_ram_new(*paddr, sz, sig, cxt->ecc_size); | 355 | *prz = persistent_ram_new(*paddr, sz, sig, cxt->ecc_size); |
342 | if (IS_ERR(*prz)) { | 356 | if (IS_ERR(*prz)) { |