[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#321718: Upgrade caused many libs to complain about "executable stack"



At Mon, 15 Aug 2005 10:12:31 -0400,
Daniel Jacobowitz wrote:
> > I don't know what the exact problem is - Does this problem occur with
> > 2.4 kernel?  Can all furious PaX reports be fixed using 2.6 kernel?
> 
> This is separate from the PaX problems - it's stock 2.4.  I don't know
> why it happens, but someone would need to set up a 2.4 system to debug
> it on.

Thanks, I confirmed the problem.

When I booted up with 2.4.18-bf2.4, then I invoked "ssh",
libcrypto.so.0.9.7 got Error 14.  But kernel 2.4.26-1-686 does not
break.  As you already stated, this is because 2.4.18-bf2.4 returns
EFAULT instead of ENOMEM when the second of problematic mprotect() is
called during resolving libcrypto.so [1].  Then I looked at
/proc/pid/maps.  It says even on 2.4.18-bf2.4 [2]:

	bffff000-c0000000 rwxp 00000000 00:00 0

So the problem is the return value of mprotect is changed during
2.4.18 and 2.4.26.  I found some mail of this modifications:

	http://www.linux-mips.org/archives/linux-mips/2002-06/msg00215.html

	--- mm/mprotect.c       4 Mar 2002 11:13:35 -0000       1.1.1.1
	+++ mm/mprotect.c       25 Jun 2002 07:00:55 -0000
	@@ -284,7 +284,7 @@
	        down_write(&current->mm->mmap_sem);
	 
	        vma = find_vma_prev(current->mm, start, &prev);
	-       error = -EFAULT;
	+       error = -ENOMEM;
	        if (!vma || vma->vm_start > start)
	                goto out;
	 
	@@ -317,7 +317,7 @@
	                nstart = tmp;
	                vma = next;
	                if (!vma || vma->vm_start != nstart) {
	-                       error = -EFAULT;
	+                       error = -ENOMEM;
	                        goto out;
	                }
	        }

I found 2.6 kernel changelog said (Hi Adrian!):

    <akpm@osdl.org>
	[PATCH] mprotect return value fix
	From: Marc-Christian Petersen <m.c.p@wolk-project.de>
	2.4 patch from Adrian Bunk.
	ERRORS
	    The mprotect() function shall fail if:
	    ...
	    [ENOMEM]
	        Addresses in the range [addr,addr+len) are invalid for the
	        address space of a process, or specify one or more pages which are
	        not mapped.

This modification was done because mprotect returned EFAULT instead of
ENOMEM, that was simply POSIX violation.  The actual problem is linux
kernel 2.4.  But in order to work glibc 2.3.5 on etch, we need to fix
adhoc patch to change dl-execstack.c.  I don't know it's acceptable
for upstream, but it's worth fixing.  If it'll be rejected, this patch
should be marked as "until-etch" if etch does not support any 2.4
kernel hopefully.  Now the patch that I have not tested yet.  Is this
solution desired for the next 2.3.5-4?

	--- sysdeps/unix/sysv/linux/dl-execstack.c.gotom	2005-08-18 20:55:21.448088096 +0900
	+++ sysdeps/unix/sysv/linux/dl-execstack.c	2005-08-18 20:57:02.500725760 +0900
	@@ -84,7 +84,7 @@
	 	page -= size;
	       else
	 	{
	-	  if (errno != ENOMEM)	/* Unexpected failure mode.  */
	+	  if (errno != (ENOMEM | EFAULT))	/* Unexpected failure mode.  */
	 	    return errno;
	 
	 	  if (size == GLRO(dl_pagesize))
	@@ -107,7 +107,7 @@
	 	page += size;
	       else
	 	{
	-	  if (errno != ENOMEM)	/* Unexpected failure mode.  */
	+	  if (errno != (ENOMEM | EFAULT))	/* Unexpected failure mode.  */
	 	    return errno;
	 
	 	  if (size == GLRO(dl_pagesize))

BTW, I found the similar problem (which I checked for 2.4.19):

	http://lists.debian.org/debian-glibc/2003/02/msg00353.html

Regards,
-- gotom

[1]
2.4.18:
  mprotect(0xbffff000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC|PROT_GROWSDOWN) = -1 EINVAL (Invalid argument)
  mprotect(0xbfff8000, 32768, PROT_READ|PROT_WRITE|PROT_EXEC) = -1 EFAULT (Bad address)
2.4.26:
  mprotect(0xbffff000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC|PROT_GROWSDOWN) = -1 EINVAL (Invalid argument)
  mprotect(0xbfff8000, 32768, PROT_READ|PROT_WRITE|PROT_EXEC) = -1 ENOMEM (Cannot allocate memory)
  mprotect(0xbfffc000, 16384, PROT_READ|PROT_WRITE|PROT_EXEC) = -1 ENOMEM (Cannot allocate memory)
  mprotect(0xbfffe000, 8192, PROT_READ|PROT_WRITE|PROT_EXEC) = -1 ENOMEM (Cannot allocate memory)
  mprotect(0xbffff000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
  mprotect(0xbfffe000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC) = -1 ENOMEM (Cannot allocate memory)
2.6.9:
  mprotect(0xbffff000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC|PROT_GROWSDOWN) = 0

[2]
2.6 kernel: bffff000-c0000000 rwxp bffff000 00:00 0 



Reply to: