[PATCH] fix for memory corruption from /proc/kcore access

Linux Kernel Mailing List <[email protected]>
Newsgroups gmane.linux.kernel.commits.2-4
Message-ID <[email protected]>
ChangeSet 1.1539.1.1, 2005/02/03 13:17:21-02:00, [email protected]

	[PATCH] fix for memory corruption from /proc/kcore access
	
	A fairly nasty memory corruption potential exists when
	/proc/kcore is accessed and there are at least 62 vmalloc'd areas.
	
	The problem is that get_kcore_size() does not properly account for
	the elf_prstatus, elf_prpsinfo, and task_struct structure sizes in
	the fabricated ELF header, and then elf_kcore_store_hdr() and its
	associated calls to storenote() will possibly overrun the "elf_buf"
	buffer allocated by read_kcore().  Because the requested buffer size
	is rounded up to a page multiple, only certain ranges of counts of
	vmalloc'd areas will actually lead to a memory corruption.  When it
	does happen, usually the end of the /proc/kcore reader's task_struct
	ends up being copied into a slab page (or sometimes into a data page)
	causing a kernel crash (or data corruption) at a later point in time.
	
	The 1st hunk of the patch below fixes this problem.  The latter 3
	hunks correct the "p_filesz" value for the note section (which is
	already initialized to 0 on line 232) as stored in the ELF header,
	but these hunks are not necessary to fix the corruption possiblity.
	
	The fix is already in 2.6.



 kcore.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)


diff -Nru a/fs/proc/kcore.c b/fs/proc/kcore.c
--- a/fs/proc/kcore.c	2005-02-07 13:03:39 -08:00
+++ b/fs/proc/kcore.c	2005-02-07 13:03:39 -08:00
@@ -136,7 +136,10 @@
 	}
 	*elf_buflen =	sizeof(struct elfhdr) + 
 			(*num_vma + 2)*sizeof(struct elf_phdr) + 
-			3 * sizeof(struct memelfnote);
+			3 * (sizeof(struct elf_note) + 4) +
+			sizeof(struct elf_prstatus) +
+			sizeof(struct elf_prpsinfo) +
+			sizeof(struct task_struct);
 	*elf_buflen = PAGE_ALIGN(*elf_buflen);
 	return (size - PAGE_OFFSET + *elf_buflen);
 }
@@ -279,7 +282,7 @@
 
 	memset(&prstatus, 0, sizeof(struct elf_prstatus));
 
-	nhdr->p_filesz	= notesize(&notes[0]);
+	nhdr->p_filesz += notesize(&notes[0]);
 	bufp = storenote(&notes[0], bufp);
 
 	/* set up the process info */
@@ -296,7 +299,7 @@
 	strcpy(prpsinfo.pr_fname, "vmlinux");
 	strncpy(prpsinfo.pr_psargs, saved_command_line, ELF_PRARGSZ);
 
-	nhdr->p_filesz	= notesize(&notes[1]);
+	nhdr->p_filesz += notesize(&notes[1]);
 	bufp = storenote(&notes[1], bufp);
 
 	/* set up the task structure */
@@ -305,7 +308,7 @@
 	notes[2].datasz	= sizeof(struct task_struct);
 	notes[2].data	= current;
 
-	nhdr->p_filesz	= notesize(&notes[2]);
+	nhdr->p_filesz += notesize(&notes[2]);
 	bufp = storenote(&notes[2], bufp);
 
 } /* end elf_kcore_store_hdr() */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.