diff options
Diffstat (limited to 'fs/proc/vmcore.c')
-rw-r--r-- | fs/proc/vmcore.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 2ca7ba047f04..88d4585b30f1 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c | |||
@@ -468,17 +468,24 @@ static int __init update_note_header_size_elf64(const Elf64_Ehdr *ehdr_ptr) | |||
468 | return rc; | 468 | return rc; |
469 | } | 469 | } |
470 | nhdr_ptr = notes_section; | 470 | nhdr_ptr = notes_section; |
471 | while (real_sz < max_sz) { | 471 | while (nhdr_ptr->n_namesz != 0) { |
472 | if (nhdr_ptr->n_namesz == 0) | ||
473 | break; | ||
474 | sz = sizeof(Elf64_Nhdr) + | 472 | sz = sizeof(Elf64_Nhdr) + |
475 | ((nhdr_ptr->n_namesz + 3) & ~3) + | 473 | ((nhdr_ptr->n_namesz + 3) & ~3) + |
476 | ((nhdr_ptr->n_descsz + 3) & ~3); | 474 | ((nhdr_ptr->n_descsz + 3) & ~3); |
475 | if ((real_sz + sz) > max_sz) { | ||
476 | pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n", | ||
477 | nhdr_ptr->n_namesz, nhdr_ptr->n_descsz); | ||
478 | break; | ||
479 | } | ||
477 | real_sz += sz; | 480 | real_sz += sz; |
478 | nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz); | 481 | nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz); |
479 | } | 482 | } |
480 | kfree(notes_section); | 483 | kfree(notes_section); |
481 | phdr_ptr->p_memsz = real_sz; | 484 | phdr_ptr->p_memsz = real_sz; |
485 | if (real_sz == 0) { | ||
486 | pr_warn("Warning: Zero PT_NOTE entries found\n"); | ||
487 | return -EINVAL; | ||
488 | } | ||
482 | } | 489 | } |
483 | 490 | ||
484 | return 0; | 491 | return 0; |
@@ -648,17 +655,24 @@ static int __init update_note_header_size_elf32(const Elf32_Ehdr *ehdr_ptr) | |||
648 | return rc; | 655 | return rc; |
649 | } | 656 | } |
650 | nhdr_ptr = notes_section; | 657 | nhdr_ptr = notes_section; |
651 | while (real_sz < max_sz) { | 658 | while (nhdr_ptr->n_namesz != 0) { |
652 | if (nhdr_ptr->n_namesz == 0) | ||
653 | break; | ||
654 | sz = sizeof(Elf32_Nhdr) + | 659 | sz = sizeof(Elf32_Nhdr) + |
655 | ((nhdr_ptr->n_namesz + 3) & ~3) + | 660 | ((nhdr_ptr->n_namesz + 3) & ~3) + |
656 | ((nhdr_ptr->n_descsz + 3) & ~3); | 661 | ((nhdr_ptr->n_descsz + 3) & ~3); |
662 | if ((real_sz + sz) > max_sz) { | ||
663 | pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n", | ||
664 | nhdr_ptr->n_namesz, nhdr_ptr->n_descsz); | ||
665 | break; | ||
666 | } | ||
657 | real_sz += sz; | 667 | real_sz += sz; |
658 | nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz); | 668 | nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz); |
659 | } | 669 | } |
660 | kfree(notes_section); | 670 | kfree(notes_section); |
661 | phdr_ptr->p_memsz = real_sz; | 671 | phdr_ptr->p_memsz = real_sz; |
672 | if (real_sz == 0) { | ||
673 | pr_warn("Warning: Zero PT_NOTE entries found\n"); | ||
674 | return -EINVAL; | ||
675 | } | ||
662 | } | 676 | } |
663 | 677 | ||
664 | return 0; | 678 | return 0; |