Date: Sat, 29 May 2004 01:07:15 +1000 (EST) From: Bruce Evans <bde@zeta.org.au> To: Willem Jan Withagen <wjw@withagen.nl> Cc: freebsd-current@freebsd.org Subject: Re: Possible bug in malloc-code Message-ID: <20040529005036.N15392@gamplex.bde.org> In-Reply-To: <079001c444bf$830965d0$471b3dd4@dual> References: <074501c44449$3ab41bc0$471b3dd4@dual><20040528011551.GB48226@xor.obsecurity.org> <079001c444bf$830965d0$471b3dd4@dual>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 28 May 2004, Willem Jan Withagen wrote: > ... > Didn't really work: > > The process itself: > Alloc: n = 335544320, ADR = 0x00000000485D7000 > Alloc: n = 402653184, ADR = 0x000000005C5D7000 > Alloc: n = 469762048, ADR = 0x00000000745D7000 > Alloc: n = 536870912, ADR = 0xFFFFFFFF905D7000 > Free: n = 536870912, ADR = 0xFFFFFFFF905D7000 > rMemoryDrv in free(): error: junk pointer, too high to make sense > > On the console: > panic: ffs_write: uio->uio_resid < 0 > at line 602 in file /home2/src/sys/ufs/ffs/ffs_vnops.c > cpuid = 1; > Stack backtrace: > backtrace() at backtrace+0x17 > __panic() at __panic+0x1e4 > ffs_write() at ffs_write+0x162 > vn_rdwr() at vn_rdwr+0x164 > vn_rdwr_inchunks() at vn_rdwr_inchunks+0x80 > elf64_coredump() at elf64_coredump+0x113 > coredump() at coredump+0x586 > sigexit() at sigexit+0x72 > postsig() at postsig+0x1be > ast() at ast+0x417 > Xfast_syscall() at Xfast_syscall+0xdd > --- syscall (0), rip = 0x20067c8ec, rsp = 0x7fffffffe878, rbp = 0x2006df6c0 --- > > So what next.... > It is VERY reproduceable, so with guidance on what to look at. > I'm more than willing to up my skills and get to the bottom of this. If a section is larger than INT_MAX, then overflow seems to occur here in __elfN_coredump(): % for (i = 0; i < seginfo.count; i++) { % error = vn_rdwr_inchunks(UIO_WRITE, vp, % (caddr_t)php->p_vaddr, php->p_filesz, offset, ^^^^^^^^^^^^^ % UIO_USERSPACE, IO_DIRECT, cred, NOCRED, NULL, td); php->p_filesz has type u_int64_t on 64-bit machines, but here it gets silently converted to int, so it overflows if the size is larger than INT_MAX. (Overflow may occur even on 32-bit machines, but it's harder to fit a section larger than INT_MAX on a 32-bit machine.) If ints are 32-bits 2's complement and the section size is between 2^31 and 2^32-1 inclusive, then the above asks vn_rdwr() a negative length. The negative length apparently gets as far as ffs_write() before causing a panic. It;s a longstanding bug that ssize_t is 64 bits and SSIZE_MAX is 2^63-1 on 64 bit machines, but writes from userland are limited to INT_MAX (normally 2^31-1), so 64-bit applications would have a hard time writing huge amounts. Core dumps apparently have the same problem writing large sections. A text section with size 2GB would be huge, but a data section with size 2GB is just large. The traceback should show the args, but that seems to be broken for amd64's. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040529005036.N15392>