This is the mail archive of the glibc-bugs@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libc/227] possible problem with ld.so and brk management


------- Additional Comments From pageexec at freemail dot hu  2004-08-14 21:00 -------
> In the Linux 2.6 and 2.4 sources I have on hand, the kernel always starts the
> brk value at the next page boundary.  So I can't see how this would come up.
> If there is an extant mainline Linux kernel that behaves as you say, then 
glibc
> might change to accomodate that.  Is there one?

does http://www.kernel.org./pub/linux/kernel/v2.4/linux-2.4.27.tar.bz2 pass as
an extant enough kernel ;-)?

the relevant bits from 'egrep -n -B1 elf_brk fs/binfmt_elf.c':

437:    unsigned long elf_bss, k, elf_brk;
--
501:    elf_brk = 0;
--
710-            k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
711:            if (k > elf_brk)
712:                    elf_brk = k;
--
717:    elf_brk += load_bias;
--
764:    current->mm->start_brk = current->mm->brk = elf_brk;

as you probably know, the sys_brk() syscall operates on mm->brk which based on
the above snippet is obviously not explicitly page aligned at all (it's set on
line 764 and elf_brk = p_vaddr + p_memsz which can be page aligned only by
chance, not in general). you can confirm it by simply strace'ing something,
the first brk(0) call in ld.so will show you the non-page aligned value quite
nicely.

to actually observe the bug i described you need to add a small amount of
randomization to this brk value (less than PAGE_SIZE, you can accomodate the
code from PaX or Exec-Shield), then run some applications through ld.so.

in my case what made the bug visible was when lazy PLT resolution tried to
access a field in the link_map structure of the main executable which by that
time had become garbled (as it was allocated in the fractional page and also
reused by a later malloc()). in general, any persistent allocation that ends
up in that fractional page is subject to corruption.

as for 2.6, the behaviour has changed there, fs/binfmt_elf.c:set_brk()
explicitly sets mm->brk to a page aligned value. this however presents another
problem which i think you're also aware of already: there can be applications
that assume that brk(0) = _end on startup (i recall emacs being one and maybe
the only example of this), so the 2.6 kernel breaks that assumption. not to
mention that it's pointless to explicitly align brk given that the application
can set it later to any alignment.

for me the most important consequence of this unnecessary alignment is that
we lose precious bits that we could otherwise randomize, or rather, we would
had i not explicitly reverted this 2.6 change in PaX - under Exec-Shield you
do lose the lower PAGE_SHIFT bits of brk randomization.

> If you want to experiment with a change, you can try out the attached patch.

thanks, i'll give it a try, but it already looks good to me.

> This patch works in the sense that it doesn't cause trouble, but since I
> cannot reproduce the problem you describe, I cannot confirm that it would
> fix it.

what did you do to reproduce the problem?

in any case, if you agree that it is a bug in ld.so to use and not release
memory that later will be used by other allocators then it has to be fixed.
if you think it's proper behaviour in ld.so then i'd like to know why.

-- 


http://sources.redhat.com/bugzilla/show_bug.cgi?id=227

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]