linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Marcelo Tosatti <marcelo.tosatti@cyclades.com>
To: Lukasz Trabinski <lukasz@wsisiz.edu.pl>
Cc: linux-kernel@vger.kernel.org
Subject: Re: uselib()  & 2.6.X?
Date: Fri, 7 Jan 2005 15:07:12 -0200	[thread overview]
Message-ID: <20050107170712.GK29176@logos.cnet> (raw)
In-Reply-To: <Pine.LNX.4.58LT.0501071648160.30645@oceanic.wsisiz.edu.pl>

[-- Attachment #1: Type: text/plain, Size: 672 bytes --]

On Fri, Jan 07, 2005 at 04:59:22PM +0100, Lukasz Trabinski wrote:
> Hello
> 
> 
> http://isec.pl/vulnerabilities/isec-0021-uselib.txt
> 
> [...]
> Locally  exploitable  flaws  have  been found in the Linux binary format
> loaders'  uselib()  functions  that  allow  local  users  to  gain  root
> privileges.
> [...]
> Version:   2.4 up to and including 2.4.29-rc2, 2.6 up to and including 2.6.10
> [...]
> 
> It's was fixed by Marcelo on 2.4.29-rc1. Thank's :)
> What about 2.6.X? Is any patch available? I don't see any changes 
> around binfmt_elf in 2.6.10-bk10?

2.6.10-ac contains a version of the fix.

Attached is what going to be merged in mainline, most likely.

[-- Attachment #2: 2.6.10-mm1-brk-locked.patch --]
[-- Type: text/plain, Size: 7230 bytes --]

diff -Nur linux-2.6.10.orig/arch/mips/kernel/irixelf.c linux-2.6.10/arch/mips/kernel/irixelf.c
--- linux-2.6.10.orig/arch/mips/kernel/irixelf.c	2005-01-03 16:17:00.000000000 -0200
+++ linux-2.6.10/arch/mips/kernel/irixelf.c	2005-01-03 16:44:59.909144520 -0200
@@ -127,7 +127,7 @@
 	end = PAGE_ALIGN(end);
 	if (end <= start)
 		return;
-	do_brk(start, end - start);
+	do_brk_locked(start, end - start);
 }
 
 
diff -Nur linux-2.6.10.orig/arch/x86_64/ia32/ia32_aout.c linux-2.6.10/arch/x86_64/ia32/ia32_aout.c
--- linux-2.6.10.orig/arch/x86_64/ia32/ia32_aout.c	2005-01-03 16:17:04.000000000 -0200
+++ linux-2.6.10/arch/x86_64/ia32/ia32_aout.c	2005-01-03 16:46:53.846823360 -0200
@@ -115,7 +115,7 @@
 	end = PAGE_ALIGN(end);
 	if (end <= start)
 		return;
-	do_brk(start, end - start);
+	do_brk_locked(start, end - start);
 }
 
 #if CORE_DUMP
@@ -325,7 +325,7 @@
 		pos = 32;
 		map_size = ex.a_text+ex.a_data;
 
-		error = do_brk(text_addr & PAGE_MASK, map_size);
+		error = do_brk_locked(text_addr & PAGE_MASK, map_size);
 		if (error != (text_addr & PAGE_MASK)) {
 			send_sig(SIGKILL, current, 0);
 			return error;
@@ -361,7 +361,7 @@
 
 		if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {
 			loff_t pos = fd_offset;
-			do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
+			do_brk_locked(N_TXTADDR(ex), ex.a_text+ex.a_data);
 			bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex),
 					ex.a_text+ex.a_data, &pos);
 			flush_icache_range((unsigned long) N_TXTADDR(ex),
@@ -470,7 +470,7 @@
 		}
 #endif
 
-		do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
+		do_brk_locked(start_addr, ex.a_text + ex.a_data + ex.a_bss);
 		
 		file->f_op->read(file, (char *)start_addr,
 			ex.a_text + ex.a_data, &pos);
@@ -494,7 +494,7 @@
 	len = PAGE_ALIGN(ex.a_text + ex.a_data);
 	bss = ex.a_text + ex.a_data + ex.a_bss;
 	if (bss > len) {
-		error = do_brk(start_addr + len, bss - len);
+		error = do_brk_locked(start_addr + len, bss - len);
 		retval = error;
 		if (error != start_addr + len)
 			goto out;
diff -Nur linux-2.6.10.orig/fs/binfmt_aout.c linux-2.6.10/fs/binfmt_aout.c
--- linux-2.6.10.orig/fs/binfmt_aout.c	2005-01-03 16:17:07.000000000 -0200
+++ linux-2.6.10/fs/binfmt_aout.c	2005-01-03 16:42:25.212661960 -0200
@@ -50,7 +50,7 @@
 	start = PAGE_ALIGN(start);
 	end = PAGE_ALIGN(end);
 	if (end > start) {
-		unsigned long addr = do_brk(start, end - start);
+		unsigned long addr = do_brk_locked(start, end - start);
 		if (BAD_ADDR(addr))
 			return addr;
 	}
@@ -323,10 +323,10 @@
 		loff_t pos = fd_offset;
 		/* Fuck me plenty... */
 		/* <AOL></AOL> */
-		error = do_brk(N_TXTADDR(ex), ex.a_text);
+		error = do_brk_locked(N_TXTADDR(ex), ex.a_text);
 		bprm->file->f_op->read(bprm->file, (char *) N_TXTADDR(ex),
 			  ex.a_text, &pos);
-		error = do_brk(N_DATADDR(ex), ex.a_data);
+		error = do_brk_locked(N_DATADDR(ex), ex.a_data);
 		bprm->file->f_op->read(bprm->file, (char *) N_DATADDR(ex),
 			  ex.a_data, &pos);
 		goto beyond_if;
@@ -347,7 +347,7 @@
 		map_size = ex.a_text+ex.a_data;
 #endif
 
-		error = do_brk(text_addr & PAGE_MASK, map_size);
+		error = do_brk_locked(text_addr & PAGE_MASK, map_size);
 		if (error != (text_addr & PAGE_MASK)) {
 			send_sig(SIGKILL, current, 0);
 			return error;
@@ -382,7 +382,7 @@
 
 		if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {
 			loff_t pos = fd_offset;
-			do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
+			do_brk_locked(N_TXTADDR(ex), ex.a_text+ex.a_data);
 			bprm->file->f_op->read(bprm->file,
 					(char __user *)N_TXTADDR(ex),
 					ex.a_text+ex.a_data, &pos);
@@ -488,7 +488,7 @@
 			error_time = jiffies;
 		}
 
-		do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
+		do_brk_locked(start_addr, ex.a_text + ex.a_data + ex.a_bss);
 		
 		file->f_op->read(file, (char __user *)start_addr,
 			ex.a_text + ex.a_data, &pos);
@@ -512,7 +512,7 @@
 	len = PAGE_ALIGN(ex.a_text + ex.a_data);
 	bss = ex.a_text + ex.a_data + ex.a_bss;
 	if (bss > len) {
-		error = do_brk(start_addr + len, bss - len);
+		error = do_brk_locked(start_addr + len, bss - len);
 		retval = error;
 		if (error != start_addr + len)
 			goto out;
diff -Nur linux-2.6.10.orig/fs/binfmt_elf.c linux-2.6.10/fs/binfmt_elf.c
--- linux-2.6.10.orig/fs/binfmt_elf.c	2005-01-03 16:17:07.000000000 -0200
+++ linux-2.6.10/fs/binfmt_elf.c	2005-01-03 16:43:03.265876992 -0200
@@ -88,7 +88,7 @@
 	start = ELF_PAGEALIGN(start);
 	end = ELF_PAGEALIGN(end);
 	if (end > start) {
-		unsigned long addr = do_brk(start, end - start);
+		unsigned long addr = do_brk_locked(start, end - start);
 		if (BAD_ADDR(addr))
 			return addr;
 	}
@@ -408,7 +408,7 @@
 
 	/* Map the last of the bss segment */
 	if (last_bss > elf_bss) {
-		error = do_brk(elf_bss, last_bss - elf_bss);
+		error = do_brk_locked(elf_bss, last_bss - elf_bss);
 		if (BAD_ADDR(error))
 			goto out_close;
 	}
@@ -448,7 +448,7 @@
 		goto out;
 	}
 
-	do_brk(0, text_data);
+	do_brk_locked(0, text_data);
 	if (!interpreter->f_op || !interpreter->f_op->read)
 		goto out;
 	if (interpreter->f_op->read(interpreter, addr, text_data, &offset) < 0)
@@ -456,7 +456,7 @@
 	flush_icache_range((unsigned long)addr,
 	                   (unsigned long)addr + text_data);
 
-	do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1),
+	do_brk_locked(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1),
 		interp_ex->a_bss);
 	elf_entry = interp_ex->a_entry;
 
@@ -1025,7 +1025,7 @@
 	len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr + ELF_MIN_ALIGN - 1);
 	bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
 	if (bss > len)
-		do_brk(len, bss - len);
+		do_brk_locked(len, bss - len);
 	error = 0;
 
 out_free_ph:
diff -Nur linux-2.6.10.orig/include/linux/mm.h linux-2.6.10/include/linux/mm.h
--- linux-2.6.10.orig/include/linux/mm.h	2005-01-03 16:17:05.000000000 -0200
+++ linux-2.6.10/include/linux/mm.h	2005-01-03 16:51:55.686936688 -0200
@@ -751,6 +751,7 @@
 extern int do_munmap(struct mm_struct *, unsigned long, size_t);
 
 extern unsigned long do_brk(unsigned long, unsigned long);
+extern unsigned long do_brk_locked(unsigned long, unsigned long);
 
 /* filemap.c */
 extern unsigned long page_unuse(struct page *);
diff -Nur linux-2.6.10.orig/mm/mmap.c linux-2.6.10/mm/mmap.c
--- linux-2.6.10.orig/mm/mmap.c	2005-01-03 16:17:07.000000000 -0200
+++ linux-2.6.10/mm/mmap.c	2005-01-03 16:51:17.000000000 -0200
@@ -1859,6 +1859,20 @@
 
 EXPORT_SYMBOL(do_brk);
 
+/* locking version of do_brk. */
+unsigned long do_brk_locked(unsigned long addr, unsigned long len)
+{
+	unsigned long ret;
+
+	down_write(&current->mm->mmap_sem);
+	ret = do_brk(addr, len);
+	up_write(&current->mm->mmap_sem);
+
+	return ret;
+}
+
+EXPORT_SYMBOL(do_brk_locked);
+
 /* Release all mmaps. */
 void exit_mmap(struct mm_struct *mm)
 {
diff -Nur linux-2.6.10.orig/mm/nommu.c linux-2.6.10/mm/nommu.c
--- linux-2.6.10.orig/mm/nommu.c	2005-01-03 16:17:07.000000000 -0200
+++ linux-2.6.10/mm/nommu.c	2005-01-03 16:52:31.000000000 -0200
@@ -857,6 +857,11 @@
 	return -ENOMEM;
 }
 
+unsigned long do_brk_locked(unsigned long addr, unsigned long len)
+{
+	return -ENOMEM;
+}
+
 /*
  * Expand (or shrink) an existing mapping, potentially moving it at the
  * same time (controlled by the MREMAP_MAYMOVE flag and available VM space)

  reply	other threads:[~2005-01-07 20:00 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-01-07 15:59 uselib() & 2.6.X? Lukasz Trabinski
2005-01-07 17:07 ` Marcelo Tosatti [this message]
2005-01-07 20:27   ` linux-os
2005-01-07 22:29     ` Athanasius
2005-01-07 22:49   ` Alan Cox
2005-01-08  0:15     ` Linus Torvalds
2005-01-07 22:12       ` Marcelo Tosatti
2005-01-08 18:46         ` Linus Torvalds
2005-01-08 18:28           ` Marcelo Tosatti
2005-01-09  1:38             ` Linus Torvalds
2005-01-09 11:06               ` Marcelo Tosatti
2005-01-10  8:34                 ` Frank Steiner
2005-01-10 16:51                   ` Marcelo Tosatti
2005-01-10 18:28                   ` Alan Cox
2005-01-11  7:49                     ` Frank Steiner
2005-01-08 21:07           ` Andreas Schwab
2005-01-08 22:30             ` Barry K. Nathan
2005-01-08 23:21             ` Andi Kleen
2005-01-08 23:30               ` Alan Cox
2005-01-09  0:57                 ` Andi Kleen
2005-01-09  0:49             ` Andries Brouwer
2005-01-09  2:21               ` Jesper Juhl
2005-01-09  2:17                 ` Andries Brouwer
2005-01-08 21:47           ` Alan Cox
2005-01-11 22:51           ` [PATCH] make uselib configurable (was Re: uselib() & 2.6.X?) Barry K. Nathan
2005-01-11 23:42             ` Jesper Juhl
2005-01-11 23:59             ` Andries Brouwer
2005-01-12  1:06               ` Jesper Juhl
2005-01-12  1:18                 ` David Lang
2005-01-11 22:36                   ` Marcelo Tosatti
2005-01-12  2:32                     ` Barry K. Nathan
2005-01-12  0:56                       ` Marcelo Tosatti
2005-01-12  6:10                         ` Barry K. Nathan
2005-01-12 16:47                           ` Adrian Bunk
2005-01-12 17:10                             ` Barry K. Nathan
2005-01-12 20:16                     ` Matt Mackall
2005-01-12  2:12               ` Barry K. Nathan
2005-01-12  2:23                 ` David Lang
2005-01-12  2:30                 ` Adrian Bunk
2005-01-12  5:11                 ` Stephen Pollei
2005-01-12 16:54                   ` Adrian Bunk
2005-01-12  7:58               ` Christoph Hellwig

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=20050107170712.GK29176@logos.cnet \
    --to=marcelo.tosatti@cyclades.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lukasz@wsisiz.edu.pl \
    /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;
as well as URLs for NNTP newsgroup(s).