mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Baoquan He <bhe@redhat.com>
To: linux-kernel@vger.kernel.org, ncroxon@redhat.com,
	dyoung@redhat.com, mhuang@redhat.com
Cc: Baoquan He <bhe@redhat.com>
Subject: [RHEL6.8 Patch 2/3] vmcore: prevent PT_NOTE p_memsz overflow during header update
Date: Thu, 16 Jul 2015 16:46:59 +0800	[thread overview]
Message-ID: <1437036437-25408-5-git-send-email-bhe@redhat.com> (raw)
In-Reply-To: <1437036437-25408-1-git-send-email-bhe@redhat.com>

Resolves: bz1236437
https://bugzilla.redhat.com/show_bug.cgi?id=1236437

Brew build:
https://brewweb.devel.redhat.com/taskinfo?taskID=9499237

This is back ported from upstream. Conflicts existed since there's no
update_note_header_size_elf64 yet in rhel6.

In commit 087350c9dcf1b38c597b31d7761f7366e2866e6b the notes size adding
in "for loop" is changed to "while loop". In this patch only this code
snippet is back ported since it can make later back port easier.

commit 38dfac843cb6d7be1874888839817404a15a6b3c
Author: Greg Pearson <greg.pearson@hp.com>
Date:   Mon Feb 10 14:25:36 2014 -0800

    vmcore: prevent PT_NOTE p_memsz overflow during header update

    Currently, update_note_header_size_elf64() and
    update_note_header_size_elf32() will add the size of a PT_NOTE entry to
    real_sz even if that causes real_sz to exceeds max_sz.  This patch
    corrects the while loop logic in those routines to ensure that does not
    happen and prints a warning if a PT_NOTE entry is dropped.  If zero
    PT_NOTE entries are found or this condition is encountered because the
    only entry was dropped, a warning is printed and an error is returned.

    One possible negative side effect of exceeding the max_sz limit is an
    allocation failure in merge_note_headers_elf64() or
    merge_note_headers_elf32() which would produce console output such as
    the following while booting the crash kernel.

      vmalloc: allocation failure: 14076997632 bytes
      swapper/0: page allocation failure: order:0, mode:0x80d2
      CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.10.0-gbp1 #7
      Call Trace:
        dump_stack+0x19/0x1b
        warn_alloc_failed+0xf0/0x160
        __vmalloc_node_range+0x19e/0x250
        vmalloc_user+0x4c/0x70
        merge_note_headers_elf64.constprop.9+0x116/0x24a
        vmcore_init+0x2d4/0x76c
        do_one_initcall+0xe2/0x190
        kernel_init_freeable+0x17c/0x207
        kernel_init+0xe/0x180
        ret_from_fork+0x7c/0xb0

      Kdump: vmcore not initialized

      kdump: dump target is /dev/sda4
      kdump: saving to /sysroot//var/crash/127.0.0.1-2014.01.28-13:58:52/
      kdump: saving vmcore-dmesg.txt
      Cannot open /proc/vmcore: No such file or directory
      kdump: saving vmcore-dmesg.txt failed
      kdump: saving vmcore
      kdump: saving vmcore failed

    This type of failure has been seen on a four socket prototype system
    with certain memory configurations.  Most PT_NOTE sections have a single
    entry similar to:

      n_namesz = 0x5
      n_descsz = 0x150
      n_type   = 0x1

    Occasionally, a second entry is encountered with very large n_namesz and
    n_descsz sizes:

      n_namesz = 0x80000008
      n_descsz = 0x510ae163
      n_type   = 0x80000008

    Not yet sure of the source of these extra entries, they seem bogus, but
    they shouldn't cause crash dump to fail.

    Signed-off-by: Greg Pearson <greg.pearson@hp.com>
    Acked-by: Vivek Goyal <vgoyal@redhat.com>
    Cc: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
    Cc: Michael Holzheu <holzheu@linux.vnet.ibm.com>
    Cc: "Eric W. Biederman" <ebiederm@xmission.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Signed-off-by: Baoquan He <bhe@redhat.com>
---
 fs/proc/vmcore.c | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index b53862a..97c950b 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -217,7 +217,6 @@ static int __init merge_note_headers_elf64(char *elfptr, size_t *elfsz,
 	ehdr_ptr = (Elf64_Ehdr *)elfptr;
 	phdr_ptr = (Elf64_Phdr*)(elfptr + sizeof(Elf64_Ehdr));
 	for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) {
-		int j;
 		void *notes_section;
 		struct vmcore *new;
 		u64 offset, max_sz, sz, real_sz = 0;
@@ -235,12 +234,15 @@ static int __init merge_note_headers_elf64(char *elfptr, size_t *elfsz,
 			return rc;
 		}
 		nhdr_ptr = notes_section;
-		for (j = 0; j < max_sz; j += sz) {
-			if (nhdr_ptr->n_namesz == 0)
-				break;
+		while (nhdr_ptr->n_namesz != 0) {
 			sz = sizeof(Elf64_Nhdr) +
 				((nhdr_ptr->n_namesz + 3) & ~3) +
 				((nhdr_ptr->n_descsz + 3) & ~3);
+			if ((real_sz + sz) > max_sz) {
+				pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n",
+					nhdr_ptr->n_namesz, nhdr_ptr->n_descsz);
+				break;
+			}
 			real_sz += sz;
 			nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz);
 		}
@@ -256,6 +258,10 @@ static int __init merge_note_headers_elf64(char *elfptr, size_t *elfsz,
 		list_add_tail(&new->list, vc_list);
 		phdr_sz += real_sz;
 		kfree(notes_section);
+		if (real_sz == 0) {
+			pr_warn("Warning: Zero PT_NOTE entries found\n");
+			return -EINVAL;
+		}
 	}
 
 	/* Prepare merged PT_NOTE program header. */
@@ -298,7 +304,6 @@ static int __init merge_note_headers_elf32(char *elfptr, size_t *elfsz,
 	ehdr_ptr = (Elf32_Ehdr *)elfptr;
 	phdr_ptr = (Elf32_Phdr*)(elfptr + sizeof(Elf32_Ehdr));
 	for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) {
-		int j;
 		void *notes_section;
 		struct vmcore *new;
 		u64 offset, max_sz, sz, real_sz = 0;
@@ -316,12 +321,15 @@ static int __init merge_note_headers_elf32(char *elfptr, size_t *elfsz,
 			return rc;
 		}
 		nhdr_ptr = notes_section;
-		for (j = 0; j < max_sz; j += sz) {
-			if (nhdr_ptr->n_namesz == 0)
-				break;
+		while (nhdr_ptr->n_namesz != 0) {
 			sz = sizeof(Elf32_Nhdr) +
 				((nhdr_ptr->n_namesz + 3) & ~3) +
 				((nhdr_ptr->n_descsz + 3) & ~3);
+			if ((real_sz + sz) > max_sz) {
+				pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n",
+					nhdr_ptr->n_namesz, nhdr_ptr->n_descsz);
+				break;
+			}
 			real_sz += sz;
 			nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz);
 		}
@@ -337,6 +345,11 @@ static int __init merge_note_headers_elf32(char *elfptr, size_t *elfsz,
 		list_add_tail(&new->list, vc_list);
 		phdr_sz += real_sz;
 		kfree(notes_section);
+		if (real_sz == 0) {
+			pr_warn("Warning: Zero PT_NOTE entries found\n");
+			return -EINVAL;
+		}
+
 	}
 
 	/* Prepare merged PT_NOTE program header. */
-- 
2.1.0


  parent reply	other threads:[~2015-07-16  8:47 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-16  8:46 [RHEL6.8 Patch 00/19] Support mmap() on /proc/vmcore Baoquan He
2015-07-16  8:46 ` [RHEL6.8 Patch 1/3] kernel: audit/fix non-modular users of module_init in core code Baoquan He
2015-07-16  8:46 ` [RHEL6.8 Patch 01/19] [S390] zero page cache synonyms Baoquan He
2015-07-16  8:46 ` [RHEL6.8 Patch 02/19] asm-generic, mm: pgtable: consolidate zero page helpers Baoquan He
2015-07-16  8:46 ` Baoquan He [this message]
2015-07-16  8:47 ` [RHEL6.8 Patch 03/19] fs/proc/vmcore.c: add hook to read_from_oldmem() to check for non-ram pages Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 3/3] vmcore: continue vmcore initialization if PT_NOTE is found empty Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 04/19] fs/proc/vmcore.c: put if tests in the top of the while loop to reduce duplication Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 05/19] include/linux/mm.h: add PAGE_ALIGNED() helper Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 06/19] vmcore: clean up read_vmcore() Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 07/19] vmcore: allocate buffer for ELF headers on page-size alignment Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 08/19] vmcore: treat memory chunks referenced by PT_LOAD program header entries in page-size boundary in vmcore_list Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 09/19] vmalloc: make find_vm_area check in range Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 10/19] vmalloc: introduce remap_vmalloc_range_partial Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 11/19] vmcore: allocate ELF note segment in the 2nd kernel vmalloc memory Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 12/19] vmcore: allow user process to remap ELF note segment buffer Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 13/19] vmcore: calculate vmcore file size from buffer size and total size of vmcore objects Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 14/19] vmcore: support mmap() on /proc/vmcore Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 15/19] s390/kdump: Disable mmap for s390 Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 16/19] s390/kdump: Allow copy_oldmem_page() copy to virtual memory Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 17/19] vmcore: introduce remap_oldmem_pfn_range() Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 18/19] s390/vmcore: implement remap_oldmem_pfn_range for s390 Baoquan He
2015-07-16  8:47 ` [RHEL6.8 Patch 19/19] fs/proc/vmcore.c:mmap_vmcore: skip non-ram pages reported by hypervisors Baoquan He
2015-07-16 11:01 ` [RHEL6.8 Patch 00/19] Support mmap() on /proc/vmcore Baoquan He

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1437036437-25408-5-git-send-email-bhe@redhat.com \
    --to=bhe@redhat.com \
    --cc=dyoung@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhuang@redhat.com \
    --cc=ncroxon@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®