mirror of
git://sourceware.org/git/glibc.git
synced 2025-04-12 14:21:18 +08:00
Updated to fedora-glibc-20041115T0915
This commit is contained in:
parent
87ffc9aca1
commit
b3c20a361d
51
ChangeLog
51
ChangeLog
@ -1,3 +1,43 @@
|
||||
2004-11-13 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* malloc/malloc.c (malloc_state): stat_lock_* elements need only
|
||||
be defined if THREAD_STATS is defined. Remove pad0_ since it does
|
||||
not align with cache line sizes in general anyway.
|
||||
|
||||
2004-11-13 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* elf/rtld.c (print_statistics): Avoid segfaults if not all namespaces
|
||||
are used. Fix computation of num_relative_relocations on RELA
|
||||
architectures other than IA-64 and Alpha.
|
||||
|
||||
2004-11-13 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* malloc/malloc.c (_int_free): Use munmap_chunk for handling
|
||||
mmaped memory.
|
||||
|
||||
2004-11-12 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* malloc/malloc.c (_int_free): Remove test for NULL parameter.
|
||||
(_int_realloc): Call _int_free only if memory parameter is not NULL.
|
||||
|
||||
* sysdeps/unix/sysv/linux/libc_fatal.c: Add new function __libc_message
|
||||
which performs the printing and simple format string handling. The
|
||||
string is written to tty, stderr, syslog in this order, stopping after
|
||||
the first successful output.
|
||||
(__libc_fatal): Call __libc_message.
|
||||
* include/stdio.h: Declare __libc_message.
|
||||
* malloc/malloc.c (malloc_printerr): Use __libc_message.
|
||||
* debug/chk_fail.c: Also print message with __libc_message.
|
||||
* debug/test-strcpy_chk.c: Ensure that debug messages are not printed
|
||||
to the terminal or stderr.
|
||||
* debug/tst-chk1.c: Likewise.
|
||||
|
||||
* posix/Makefile: Remove gpl2lgpl variable.
|
||||
|
||||
2004-11-12 Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
|
||||
* elf/elf.h: Add 20 bit relocations R_390_*20.
|
||||
|
||||
2004-11-12 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/i386/setuid.c: Include linux/posix_types.h.
|
||||
@ -7,16 +47,9 @@
|
||||
* sysdeps/unix/sysv/linux/i386/setresuid.c: Likewise.
|
||||
* sysdeps/unix/sysv/linux/i386/setresgid.c: Likewise.
|
||||
|
||||
2004-11-11 Jakub Jelinek <jakub@redhat.com>
|
||||
2004-11-12 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
* debug/chk_fail.c: Include errno.h and string.h.
|
||||
(__chk_fail): Write a short message to stderr.
|
||||
* debug/tst-chk1.c: Include fcntl.h.
|
||||
(do_test): Redirect stderr to /dev/null.
|
||||
* debug/test-strcpy_chk.c: Include fcntl.h.
|
||||
(test_main): Redirect stderr to /dev/null.
|
||||
(do_one_test, do_random_tests): Use printf instead of
|
||||
error.
|
||||
* nis/ypclnt.c (ypprot_err): Fix "minor optimizations".
|
||||
|
||||
2004-11-12 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
/* Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
@ -16,27 +17,14 @@
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <abort-instr.h>
|
||||
|
||||
|
||||
void
|
||||
__attribute__ ((noreturn))
|
||||
__chk_fail (void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
const char *text = "*** buffer overflow detected ***\n";
|
||||
TEMP_FAILURE_RETRY (write (STDERR_FILENO, text, strlen (text)));
|
||||
/* This will leave a nice backtrace. */
|
||||
abort ();
|
||||
#ifdef ABORT_INSTRUCTION
|
||||
ABORT_INSTRUCTION;
|
||||
#endif
|
||||
_exit (127);
|
||||
}
|
||||
__libc_fatal ("*** buffer overflow detected ***\n");
|
||||
}
|
||||
libc_hidden_def (__chk_fail)
|
||||
|
@ -46,9 +46,10 @@ simple_strcpy_chk (char *dst, const char *src, size_t len)
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
volatile int chk_fail_ok;
|
||||
jmp_buf chk_fail_buf;
|
||||
@ -81,8 +82,8 @@ do_one_test (impl_t *impl, char *dst, const char *src,
|
||||
if (setjmp (chk_fail_buf) == 0)
|
||||
{
|
||||
res = CALL (impl, dst, src, dlen);
|
||||
printf ("*** Function %s (%zd; %zd) did not __chk_fail",
|
||||
impl->name, len, dlen);
|
||||
printf ("*** Function %s (%zd; %zd) did not __chk_fail\n",
|
||||
impl->name, len, dlen);
|
||||
chk_fail_ok = 0;
|
||||
ret = 1;
|
||||
}
|
||||
@ -93,7 +94,7 @@ do_one_test (impl_t *impl, char *dst, const char *src,
|
||||
|
||||
if (res != STRCPY_RESULT (dst, len))
|
||||
{
|
||||
printf ("*** Wrong result in function %s %p %p", impl->name,
|
||||
printf ("Wrong result in function %s %p %p\n", impl->name,
|
||||
res, STRCPY_RESULT (dst, len));
|
||||
ret = 1;
|
||||
return;
|
||||
@ -101,7 +102,7 @@ do_one_test (impl_t *impl, char *dst, const char *src,
|
||||
|
||||
if (strcmp (dst, src) != 0)
|
||||
{
|
||||
printf ("*** Wrong result in function %s dst \"%s\" src \"%s\"",
|
||||
printf ("Wrong result in function %s dst \"%s\" src \"%s\"\n",
|
||||
impl->name, dst, src);
|
||||
ret = 1;
|
||||
return;
|
||||
@ -233,7 +234,7 @@ do_random_tests (void)
|
||||
if (setjmp (chk_fail_buf) == 0)
|
||||
{
|
||||
res = CALL (impl, p2 + align2, p1 + align1, dlen);
|
||||
printf ("*** Iteration %zd - did not __chk_fail", n);
|
||||
printf ("Iteration %zd - did not __chk_fail\n", n);
|
||||
chk_fail_ok = 0;
|
||||
ret = 1;
|
||||
}
|
||||
@ -244,7 +245,8 @@ do_random_tests (void)
|
||||
res = CALL (impl, p2 + align2, p1 + align1, dlen);
|
||||
if (res != STRCPY_RESULT (p2 + align2, len))
|
||||
{
|
||||
printf ("*** Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p",
|
||||
printf ("\
|
||||
Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p\n",
|
||||
n, impl->name, align1, align2, len, res,
|
||||
STRCPY_RESULT (p2 + align2, len));
|
||||
ret = 1;
|
||||
@ -253,7 +255,8 @@ do_random_tests (void)
|
||||
{
|
||||
if (p2[j - 64] != '\1')
|
||||
{
|
||||
printf ("*** Iteration %zd - garbage before, %s (%zd, %zd, %zd)",
|
||||
printf ("\
|
||||
Iteration %zd - garbage before, %s (%zd, %zd, %zd)\n",
|
||||
n, impl->name, align1, align2, len);
|
||||
ret = 1;
|
||||
break;
|
||||
@ -263,7 +266,8 @@ do_random_tests (void)
|
||||
{
|
||||
if (p2[j] != '\1')
|
||||
{
|
||||
printf ("*** Iteration %zd - garbage after, %s (%zd, %zd, %zd)",
|
||||
printf ("\
|
||||
Iteration %zd - garbage after, %s (%zd, %zd, %zd)\n",
|
||||
n, impl->name, align1, align2, len);
|
||||
ret = 1;
|
||||
break;
|
||||
@ -271,7 +275,8 @@ do_random_tests (void)
|
||||
}
|
||||
if (memcmp (p1 + align1, p2 + align2, len + 1))
|
||||
{
|
||||
printf ("*** Iteration %zd - different strings, %s (%zd, %zd, %zd)",
|
||||
printf ("\
|
||||
Iteration %zd - different strings, %s (%zd, %zd, %zd)\n",
|
||||
n, impl->name, align1, align2, len);
|
||||
ret = 1;
|
||||
}
|
||||
@ -292,8 +297,15 @@ test_main (void)
|
||||
sigaction (SIGABRT, &sa, NULL);
|
||||
|
||||
/* Avoid all the buffer overflow messages on stderr. */
|
||||
close (STDERR_FILENO);
|
||||
open ("/dev/null", O_WRONLY);
|
||||
int fd = open (_PATH_DEVNULL, O_WRONLY);
|
||||
if (fd == -1)
|
||||
close (STDERR_FILENO);
|
||||
else
|
||||
{
|
||||
dup2 (fd, STDERR_FILENO);
|
||||
close (fd);
|
||||
}
|
||||
setenv ("LIBC_FATAL_STDERR_", "1", 1);
|
||||
|
||||
test_init ();
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
@ -108,8 +109,15 @@ do_test (void)
|
||||
sigaction (SIGABRT, &sa, NULL);
|
||||
|
||||
/* Avoid all the buffer overflow messages on stderr. */
|
||||
close (STDERR_FILENO);
|
||||
open ("/dev/null", O_WRONLY);
|
||||
int fd = open (_PATH_DEVNULL, O_WRONLY);
|
||||
if (fd == -1)
|
||||
close (STDERR_FILENO);
|
||||
else
|
||||
{
|
||||
dup2 (fd, STDERR_FILENO);
|
||||
close (fd);
|
||||
}
|
||||
setenv ("LIBC_FATAL_STDERR_", "1", 1);
|
||||
|
||||
struct A { char buf1[9]; char buf2[1]; } a;
|
||||
|
||||
@ -205,7 +213,7 @@ do_test (void)
|
||||
if (memcmp (a.buf1, "aabcdabcjj", 10))
|
||||
FAIL ();
|
||||
|
||||
#if __USE_FORTIFY_LEVEL < 2 || !__GNUC_PREREQ (4, 0)
|
||||
#if __USE_FORTIFY_LEVEL < 2
|
||||
/* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2
|
||||
and sufficient GCC support, as the string operations overflow
|
||||
from a.buf1 into a.buf2. */
|
||||
@ -304,7 +312,7 @@ do_test (void)
|
||||
memset (a.buf1 + 9, 'j', l0 + 2);
|
||||
CHK_FAIL_END
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 2 && __GNUC_PREREQ (4, 0)
|
||||
#if __USE_FORTIFY_LEVEL >= 2
|
||||
# define O 0
|
||||
#else
|
||||
# define O 1
|
||||
|
@ -2402,8 +2402,13 @@ typedef Elf32_Addr Elf32_Conflict;
|
||||
#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */
|
||||
#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS
|
||||
block. */
|
||||
#define R_390_20 57 /* Direct 20 bit. */
|
||||
#define R_390_GOT20 58 /* 20 bit GOT offset. */
|
||||
#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */
|
||||
#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS
|
||||
block offset. */
|
||||
/* Keep this the last entry. */
|
||||
#define R_390_NUM 57
|
||||
#define R_390_NUM 61
|
||||
|
||||
|
||||
/* CRIS relocations. */
|
||||
|
20
elf/rtld.c
20
elf/rtld.c
@ -2444,19 +2444,29 @@ print_statistics (hp_timing_t *rtld_total_timep)
|
||||
unsigned long int num_relative_relocations = 0;
|
||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
||||
{
|
||||
if (GL(dl_ns)[ns]._ns_loaded == NULL)
|
||||
continue;
|
||||
|
||||
struct r_scope_elem *scope = &GL(dl_ns)[ns]._ns_loaded->l_searchlist;
|
||||
|
||||
for (unsigned int i = 0; i < scope->r_nlist; i++)
|
||||
{
|
||||
struct link_map *l = scope->r_list [i];
|
||||
|
||||
if (!l->l_addr)
|
||||
continue;
|
||||
|
||||
if (l->l_info[VERSYMIDX (DT_RELCOUNT)])
|
||||
if (l->l_addr != 0 && l->l_info[VERSYMIDX (DT_RELCOUNT)])
|
||||
num_relative_relocations
|
||||
+= l->l_info[VERSYMIDX (DT_RELCOUNT)]->d_un.d_val;
|
||||
if (l->l_info[VERSYMIDX (DT_RELACOUNT)])
|
||||
#ifndef ELF_MACHINE_REL_RELATIVE
|
||||
/* Relative relocations are processed on these architectures if
|
||||
library is loaded to different address than p_vaddr or
|
||||
if not prelinked. */
|
||||
if ((l->l_addr != 0 || !l->l_info[VALIDX(DT_GNU_PRELINKED)])
|
||||
&& l->l_info[VERSYMIDX (DT_RELACOUNT)])
|
||||
#else
|
||||
/* On e.g. IA-64 or Alpha, relative relocations are processed
|
||||
only if library is loaded to different address than p_vaddr. */
|
||||
if (l->l_addr != 0 && l->l_info[VERSYMIDX (DT_RELACOUNT)])
|
||||
#endif
|
||||
num_relative_relocations
|
||||
+= l->l_info[VERSYMIDX (DT_RELACOUNT)]->d_un.d_val;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
# This file is updated automatically by Makefile.
|
||||
glibc-branch := fedora
|
||||
glibc-base := HEAD
|
||||
fedora-sync-date := 2004-11-12 16:40 UTC
|
||||
fedora-sync-tag := fedora-glibc-20041112T1640
|
||||
fedora-sync-date := 2004-11-15 09:15 UTC
|
||||
fedora-sync-tag := fedora-glibc-20041115T0915
|
||||
|
@ -1,4 +1,4 @@
|
||||
%define glibcrelease 77
|
||||
%define glibcrelease 78
|
||||
%define auxarches i586 i686 athlon sparcv9 alphaev6
|
||||
%define prelinkarches noarch
|
||||
%define nptlarches i386 i686 athlon x86_64 ia64 s390 s390x sparcv9 ppc ppc64
|
||||
@ -1256,6 +1256,11 @@ rm -f *.filelist*
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Mon Nov 15 2004 Jakub Jelinek <jakub@redhat.com> 2.3.3-78
|
||||
- update from CVS
|
||||
- issue error message before aborting in __chk_fail ()
|
||||
- some more free () checking
|
||||
|
||||
* Fri Nov 12 2004 Jakub Jelinek <jakub@redhat.com> 2.3.3-77
|
||||
- update from CVS
|
||||
- speedup regex on palindromes (BZ #429)
|
||||
|
@ -62,6 +62,8 @@ extern int __gen_tempname (char *__tmpl, int __kind);
|
||||
/* Print out MESSAGE on the error output and abort. */
|
||||
extern void __libc_fatal (__const char *__message)
|
||||
__attribute__ ((__noreturn__));
|
||||
extern void __libc_message (int do_abort, __const char *__fnt, ...)
|
||||
__attribute__ ((__noreturn__));
|
||||
|
||||
/* Acquire ownership of STREAM. */
|
||||
extern void __flockfile (FILE *__stream);
|
||||
|
384
malloc/malloc.c
384
malloc/malloc.c
@ -2192,10 +2192,12 @@ typedef struct malloc_chunk* mfastbinptr;
|
||||
struct malloc_state {
|
||||
/* Serialize access. */
|
||||
mutex_t mutex;
|
||||
// Should we have padding to move the mutex to its own cache line?
|
||||
|
||||
#if THREAD_STATS
|
||||
/* Statistics for locking. Only used if THREAD_STATS is defined. */
|
||||
long stat_lock_direct, stat_lock_loop, stat_lock_wait;
|
||||
long pad0_[1]; /* try to give the mutex its own cacheline */
|
||||
#endif
|
||||
|
||||
/* The maximum chunk size to be eligible for fastbin */
|
||||
INTERNAL_SIZE_T max_fast; /* low 2 bits used as flags */
|
||||
@ -4196,191 +4198,182 @@ _int_free(mstate av, Void_t* mem)
|
||||
mchunkptr fwd; /* misc temp for linking */
|
||||
|
||||
|
||||
/* free(0) has no effect */
|
||||
if (mem != 0) {
|
||||
const char *errstr = NULL;
|
||||
const char *errstr = NULL;
|
||||
|
||||
p = mem2chunk(mem);
|
||||
size = chunksize(p);
|
||||
p = mem2chunk(mem);
|
||||
size = chunksize(p);
|
||||
|
||||
/* Little security check which won't hurt performance: the
|
||||
allocator never wrapps around at the end of the address space.
|
||||
Therefore we can exclude some size values which might appear
|
||||
here by accident or by "design" from some intruder. */
|
||||
if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0))
|
||||
{
|
||||
errstr = "free(): invalid pointer";
|
||||
errout:
|
||||
malloc_printerr (check_action, errstr, mem);
|
||||
return;
|
||||
}
|
||||
/* Little security check which won't hurt performance: the
|
||||
allocator never wrapps around at the end of the address space.
|
||||
Therefore we can exclude some size values which might appear
|
||||
here by accident or by "design" from some intruder. */
|
||||
if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0))
|
||||
{
|
||||
errstr = "free(): invalid pointer";
|
||||
errout:
|
||||
malloc_printerr (check_action, errstr, mem);
|
||||
return;
|
||||
}
|
||||
|
||||
check_inuse_chunk(av, p);
|
||||
check_inuse_chunk(av, p);
|
||||
|
||||
/*
|
||||
If eligible, place chunk on a fastbin so it can be found
|
||||
and used quickly in malloc.
|
||||
*/
|
||||
/*
|
||||
If eligible, place chunk on a fastbin so it can be found
|
||||
and used quickly in malloc.
|
||||
*/
|
||||
|
||||
if ((unsigned long)(size) <= (unsigned long)(av->max_fast)
|
||||
if ((unsigned long)(size) <= (unsigned long)(av->max_fast)
|
||||
|
||||
#if TRIM_FASTBINS
|
||||
/*
|
||||
If TRIM_FASTBINS set, don't place chunks
|
||||
bordering top into fastbins
|
||||
*/
|
||||
&& (chunk_at_offset(p, size) != av->top)
|
||||
/*
|
||||
If TRIM_FASTBINS set, don't place chunks
|
||||
bordering top into fastbins
|
||||
*/
|
||||
&& (chunk_at_offset(p, size) != av->top)
|
||||
#endif
|
||||
) {
|
||||
) {
|
||||
|
||||
set_fastchunks(av);
|
||||
fb = &(av->fastbins[fastbin_index(size)]);
|
||||
/* Another simple check: make sure the top of the bin is not the
|
||||
record we are going to add (i.e., double free). */
|
||||
if (__builtin_expect (*fb == p, 0))
|
||||
{
|
||||
errstr = "double free or corruption (fasttop)";
|
||||
goto errout;
|
||||
}
|
||||
p->fd = *fb;
|
||||
*fb = p;
|
||||
set_fastchunks(av);
|
||||
fb = &(av->fastbins[fastbin_index(size)]);
|
||||
/* Another simple check: make sure the top of the bin is not the
|
||||
record we are going to add (i.e., double free). */
|
||||
if (__builtin_expect (*fb == p, 0))
|
||||
{
|
||||
errstr = "double free or corruption (fasttop)";
|
||||
goto errout;
|
||||
}
|
||||
p->fd = *fb;
|
||||
*fb = p;
|
||||
}
|
||||
|
||||
/*
|
||||
Consolidate other non-mmapped chunks as they arrive.
|
||||
*/
|
||||
|
||||
else if (!chunk_is_mmapped(p)) {
|
||||
nextchunk = chunk_at_offset(p, size);
|
||||
|
||||
/* Lightweight tests: check whether the block is already the
|
||||
top block. */
|
||||
if (__builtin_expect (p == av->top, 0))
|
||||
{
|
||||
errstr = "double free or corruption (top)";
|
||||
goto errout;
|
||||
}
|
||||
/* Or whether the next chunk is beyond the boundaries of the arena. */
|
||||
if (__builtin_expect (contiguous (av)
|
||||
&& (char *) nextchunk
|
||||
>= ((char *) av->top + chunksize(av->top)), 0))
|
||||
{
|
||||
errstr = "double free or corruption (out)";
|
||||
goto errout;
|
||||
}
|
||||
/* Or whether the block is actually not marked used. */
|
||||
if (__builtin_expect (!prev_inuse(nextchunk), 0))
|
||||
{
|
||||
errstr = "double free or corruption (!prev)";
|
||||
goto errout;
|
||||
}
|
||||
|
||||
nextsize = chunksize(nextchunk);
|
||||
assert(nextsize > 0);
|
||||
|
||||
/* consolidate backward */
|
||||
if (!prev_inuse(p)) {
|
||||
prevsize = p->prev_size;
|
||||
size += prevsize;
|
||||
p = chunk_at_offset(p, -((long) prevsize));
|
||||
unlink(p, bck, fwd);
|
||||
}
|
||||
|
||||
if (nextchunk != av->top) {
|
||||
/* get and clear inuse bit */
|
||||
nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
|
||||
|
||||
/* consolidate forward */
|
||||
if (!nextinuse) {
|
||||
unlink(nextchunk, bck, fwd);
|
||||
size += nextsize;
|
||||
} else
|
||||
clear_inuse_bit_at_offset(nextchunk, 0);
|
||||
|
||||
/*
|
||||
Place the chunk in unsorted chunk list. Chunks are
|
||||
not placed into regular bins until after they have
|
||||
been given one chance to be used in malloc.
|
||||
*/
|
||||
|
||||
bck = unsorted_chunks(av);
|
||||
fwd = bck->fd;
|
||||
p->bk = bck;
|
||||
p->fd = fwd;
|
||||
bck->fd = p;
|
||||
fwd->bk = p;
|
||||
|
||||
set_head(p, size | PREV_INUSE);
|
||||
set_foot(p, size);
|
||||
|
||||
check_free_chunk(av, p);
|
||||
}
|
||||
|
||||
/*
|
||||
Consolidate other non-mmapped chunks as they arrive.
|
||||
*/
|
||||
|
||||
else if (!chunk_is_mmapped(p)) {
|
||||
nextchunk = chunk_at_offset(p, size);
|
||||
|
||||
/* Lightweight tests: check whether the block is already the
|
||||
top block. */
|
||||
if (__builtin_expect (p == av->top, 0))
|
||||
{
|
||||
errstr = "double free or corruption (top)";
|
||||
goto errout;
|
||||
}
|
||||
/* Or whether the next chunk is beyond the boundaries of the arena. */
|
||||
if (__builtin_expect (contiguous (av)
|
||||
&& (char *) nextchunk
|
||||
>= ((char *) av->top + chunksize(av->top)), 0))
|
||||
{
|
||||
errstr = "double free or corruption (out)";
|
||||
goto errout;
|
||||
}
|
||||
/* Or whether the block is actually not marked used. */
|
||||
if (__builtin_expect (!prev_inuse(nextchunk), 0))
|
||||
{
|
||||
errstr = "double free or corruption (!prev)";
|
||||
goto errout;
|
||||
}
|
||||
|
||||
nextsize = chunksize(nextchunk);
|
||||
assert(nextsize > 0);
|
||||
|
||||
/* consolidate backward */
|
||||
if (!prev_inuse(p)) {
|
||||
prevsize = p->prev_size;
|
||||
size += prevsize;
|
||||
p = chunk_at_offset(p, -((long) prevsize));
|
||||
unlink(p, bck, fwd);
|
||||
}
|
||||
|
||||
if (nextchunk != av->top) {
|
||||
/* get and clear inuse bit */
|
||||
nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
|
||||
|
||||
/* consolidate forward */
|
||||
if (!nextinuse) {
|
||||
unlink(nextchunk, bck, fwd);
|
||||
size += nextsize;
|
||||
} else
|
||||
clear_inuse_bit_at_offset(nextchunk, 0);
|
||||
|
||||
/*
|
||||
Place the chunk in unsorted chunk list. Chunks are
|
||||
not placed into regular bins until after they have
|
||||
been given one chance to be used in malloc.
|
||||
*/
|
||||
|
||||
bck = unsorted_chunks(av);
|
||||
fwd = bck->fd;
|
||||
p->bk = bck;
|
||||
p->fd = fwd;
|
||||
bck->fd = p;
|
||||
fwd->bk = p;
|
||||
|
||||
set_head(p, size | PREV_INUSE);
|
||||
set_foot(p, size);
|
||||
|
||||
check_free_chunk(av, p);
|
||||
}
|
||||
|
||||
/*
|
||||
If the chunk borders the current high end of memory,
|
||||
consolidate into top
|
||||
*/
|
||||
|
||||
else {
|
||||
size += nextsize;
|
||||
set_head(p, size | PREV_INUSE);
|
||||
av->top = p;
|
||||
check_chunk(av, p);
|
||||
}
|
||||
|
||||
/*
|
||||
If freeing a large space, consolidate possibly-surrounding
|
||||
chunks. Then, if the total unused topmost memory exceeds trim
|
||||
threshold, ask malloc_trim to reduce top.
|
||||
|
||||
Unless max_fast is 0, we don't know if there are fastbins
|
||||
bordering top, so we cannot tell for sure whether threshold
|
||||
has been reached unless fastbins are consolidated. But we
|
||||
don't want to consolidate on each free. As a compromise,
|
||||
consolidation is performed if FASTBIN_CONSOLIDATION_THRESHOLD
|
||||
is reached.
|
||||
*/
|
||||
|
||||
if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) {
|
||||
if (have_fastchunks(av))
|
||||
malloc_consolidate(av);
|
||||
|
||||
if (av == &main_arena) {
|
||||
#ifndef MORECORE_CANNOT_TRIM
|
||||
if ((unsigned long)(chunksize(av->top)) >=
|
||||
(unsigned long)(mp_.trim_threshold))
|
||||
sYSTRIm(mp_.top_pad, av);
|
||||
#endif
|
||||
} else {
|
||||
/* Always try heap_trim(), even if the top chunk is not
|
||||
large, because the corresponding heap might go away. */
|
||||
heap_info *heap = heap_for_ptr(top(av));
|
||||
|
||||
assert(heap->ar_ptr == av);
|
||||
heap_trim(heap, mp_.top_pad);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
If the chunk was allocated via mmap, release via munmap(). Note
|
||||
that if HAVE_MMAP is false but chunk_is_mmapped is true, then
|
||||
user must have overwritten memory. There's nothing we can do to
|
||||
catch this error unless MALLOC_DEBUG is set, in which case
|
||||
check_inuse_chunk (above) will have triggered error.
|
||||
If the chunk borders the current high end of memory,
|
||||
consolidate into top
|
||||
*/
|
||||
|
||||
else {
|
||||
#if HAVE_MMAP
|
||||
int ret;
|
||||
INTERNAL_SIZE_T offset = p->prev_size;
|
||||
mp_.n_mmaps--;
|
||||
mp_.mmapped_mem -= (size + offset);
|
||||
ret = munmap((char*)p - offset, size + offset);
|
||||
/* munmap returns non-zero on failure */
|
||||
assert(ret == 0);
|
||||
#endif
|
||||
size += nextsize;
|
||||
set_head(p, size | PREV_INUSE);
|
||||
av->top = p;
|
||||
check_chunk(av, p);
|
||||
}
|
||||
|
||||
/*
|
||||
If freeing a large space, consolidate possibly-surrounding
|
||||
chunks. Then, if the total unused topmost memory exceeds trim
|
||||
threshold, ask malloc_trim to reduce top.
|
||||
|
||||
Unless max_fast is 0, we don't know if there are fastbins
|
||||
bordering top, so we cannot tell for sure whether threshold
|
||||
has been reached unless fastbins are consolidated. But we
|
||||
don't want to consolidate on each free. As a compromise,
|
||||
consolidation is performed if FASTBIN_CONSOLIDATION_THRESHOLD
|
||||
is reached.
|
||||
*/
|
||||
|
||||
if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) {
|
||||
if (have_fastchunks(av))
|
||||
malloc_consolidate(av);
|
||||
|
||||
if (av == &main_arena) {
|
||||
#ifndef MORECORE_CANNOT_TRIM
|
||||
if ((unsigned long)(chunksize(av->top)) >=
|
||||
(unsigned long)(mp_.trim_threshold))
|
||||
sYSTRIm(mp_.top_pad, av);
|
||||
#endif
|
||||
} else {
|
||||
/* Always try heap_trim(), even if the top chunk is not
|
||||
large, because the corresponding heap might go away. */
|
||||
heap_info *heap = heap_for_ptr(top(av));
|
||||
|
||||
assert(heap->ar_ptr == av);
|
||||
heap_trim(heap, mp_.top_pad);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
If the chunk was allocated via mmap, release via munmap(). Note
|
||||
that if HAVE_MMAP is false but chunk_is_mmapped is true, then
|
||||
user must have overwritten memory. There's nothing we can do to
|
||||
catch this error unless MALLOC_DEBUG is set, in which case
|
||||
check_inuse_chunk (above) will have triggered error.
|
||||
*/
|
||||
|
||||
else {
|
||||
#if HAVE_MMAP
|
||||
munmap_chunk (p);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -4528,7 +4521,8 @@ _int_realloc(mstate av, Void_t* oldmem, size_t bytes)
|
||||
|
||||
#if REALLOC_ZERO_BYTES_FREES
|
||||
if (bytes == 0) {
|
||||
_int_free(av, oldmem);
|
||||
if (oldmem != 0)
|
||||
_int_free(av, oldmem);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -5474,45 +5468,19 @@ malloc_printerr(int action, const char *str, void *ptr)
|
||||
{
|
||||
if (action & 1)
|
||||
{
|
||||
/* output string will be ": ADDR ***\n" */
|
||||
static const char suffix[] = " ***\n";
|
||||
static const char prefix[] = ": 0x";
|
||||
char buf[sizeof (prefix) - 1 + sizeof (void *) * 2 + sizeof (suffix)];
|
||||
char *cp;
|
||||
if (action & 4)
|
||||
cp = memcpy (&buf[sizeof (buf) - 2], "\n", 2);
|
||||
else
|
||||
{
|
||||
cp = memcpy (&buf[sizeof (buf) - sizeof (suffix)], suffix,
|
||||
sizeof (suffix));
|
||||
cp = _itoa_word ((unsigned long int) ptr, cp, 16, 0);
|
||||
while (cp > &buf[sizeof (prefix) - 1])
|
||||
*--cp = '0';
|
||||
cp = memcpy (buf, prefix, sizeof (prefix) - 1);
|
||||
}
|
||||
char buf[2 * sizeof (uintptr_t) + 1];
|
||||
|
||||
struct iovec iov[3];
|
||||
int n = 0;
|
||||
if ((action & 4) == 0)
|
||||
{
|
||||
iov[0].iov_base = (char *) "*** glibc detected *** ";
|
||||
iov[0].iov_len = strlen (iov[0].iov_base);
|
||||
++n;
|
||||
}
|
||||
iov[n].iov_base = (char *) str;
|
||||
iov[n].iov_len = strlen (str);
|
||||
++n;
|
||||
iov[n].iov_base = cp;
|
||||
iov[n].iov_len = &buf[sizeof (buf) - 1] - cp;
|
||||
++n;
|
||||
if (TEMP_FAILURE_RETRY (__writev (STDERR_FILENO, iov, n)) == -1
|
||||
&& errno == EBADF)
|
||||
/* Standard error is not opened. Try using syslog. */
|
||||
syslog (LOG_ERR, "%s%s%s", (char *) iov[0].iov_base,
|
||||
(char *) iov[1].iov_base,
|
||||
n == 3 ? (const char *) iov[2].iov_base : "");
|
||||
buf[sizeof (buf) - 1] = '\0';
|
||||
char *cp = _itoa_word ((uintptr_t) ptr, &buf[sizeof (buf) - 1], 16, 0);
|
||||
while (cp > buf)
|
||||
*--cp = '0';
|
||||
|
||||
__libc_message (action & 2,
|
||||
action & 4
|
||||
? "%s\n" : "*** glibc detected *** %s: 0x%s ***\n",
|
||||
str, cp);
|
||||
}
|
||||
if (action & 2)
|
||||
else if (action & 2)
|
||||
abort ();
|
||||
}
|
||||
|
||||
|
@ -846,7 +846,7 @@ ypprot_err (const int code)
|
||||
{
|
||||
if (code < YP_VERS || code > YP_NOKEY)
|
||||
return YPERR_YPERR;
|
||||
return yp_2_yperr[code];
|
||||
return yp_2_yperr[code - YP_VERS];
|
||||
}
|
||||
libnsl_hidden_def (ypprot_err)
|
||||
|
||||
|
@ -91,7 +91,6 @@ tests += wordexp-test tst-exec tst-spawn
|
||||
endif
|
||||
others := getconf
|
||||
install-bin := getconf
|
||||
gpl2lgpl := getopt.c getopt1.c getopt.h regex.c regex.h
|
||||
|
||||
before-compile := testcases.h ptestcases.h
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1993, 1994, 1995, 1997, 2000 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1993,1994,1995,1997,2000,2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -16,44 +16,131 @@
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sysdep.h>
|
||||
#include <string.h>
|
||||
#include <sysdep.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <not-cancel.h>
|
||||
|
||||
#ifdef FATAL_PREPARE_INCLUDE
|
||||
#include FATAL_PREPARE_INCLUDE
|
||||
#endif
|
||||
|
||||
struct str_list
|
||||
{
|
||||
const char *str;
|
||||
size_t len;
|
||||
struct str_list *next;
|
||||
};
|
||||
|
||||
|
||||
/* Abort with an error message. */
|
||||
void
|
||||
__libc_fatal (message)
|
||||
const char *message;
|
||||
__libc_message (int do_abort, const char *fmt, ...)
|
||||
{
|
||||
size_t len = strlen (message);
|
||||
va_list ap;
|
||||
va_list ap_copy;
|
||||
int fd = -1;
|
||||
|
||||
va_start (ap, fmt);
|
||||
va_copy (ap_copy, ap);
|
||||
|
||||
#ifdef FATAL_PREPARE
|
||||
FATAL_PREPARE;
|
||||
#endif
|
||||
|
||||
while (len > 0)
|
||||
/* Open a descriptor for /dev/tty unless the user explicitly
|
||||
requests errors on standard error. */
|
||||
const char *on_2 = __secure_getenv ("LIBC_FATAL_STDERR_");
|
||||
if (on_2 == NULL || *on_2 == '\0')
|
||||
fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
|
||||
|
||||
if (fd == -1)
|
||||
fd = STDERR_FILENO;
|
||||
|
||||
struct str_list *list = NULL;
|
||||
int nlist = 0;
|
||||
|
||||
const char *cp = fmt;
|
||||
while (*cp != '\0')
|
||||
{
|
||||
register int count = __write (STDERR_FILENO, message, len);
|
||||
if (count > 0)
|
||||
/* Find the next "%s" or the end of the string. */
|
||||
char *next = cp;
|
||||
while (next[0] != '%' || next[1] != 's')
|
||||
{
|
||||
message += count;
|
||||
len -= count;
|
||||
next = __strchrnul (next + 1, '%');
|
||||
|
||||
if (next[0] == '\0')
|
||||
break;
|
||||
}
|
||||
else if (count < 0
|
||||
#ifdef EINTR
|
||||
&& errno != EINTR
|
||||
#endif
|
||||
)
|
||||
break;
|
||||
|
||||
/* Determine what to print. */
|
||||
const char *str;
|
||||
size_t len;
|
||||
if (cp[0] == '%' && cp[1] == 's')
|
||||
{
|
||||
str = va_arg (ap, const char *);
|
||||
len = strlen (str);
|
||||
cp += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
str = cp;
|
||||
len = next - cp;
|
||||
cp = next;
|
||||
}
|
||||
|
||||
struct str_list *newp = alloca (sizeof (struct str_list));
|
||||
newp->str = str;
|
||||
newp->len = len;
|
||||
newp->next = list;
|
||||
list = newp;
|
||||
++nlist;
|
||||
}
|
||||
|
||||
abort ();
|
||||
bool written = false;
|
||||
if (nlist > 0)
|
||||
{
|
||||
struct iovec *iov = alloca (nlist * sizeof (struct iovec));
|
||||
ssize_t total = 0;
|
||||
|
||||
for (int cnt = nlist - 1; cnt >= 0; --cnt)
|
||||
{
|
||||
iov[cnt].iov_base = list->str;
|
||||
iov[cnt].iov_len = list->len;
|
||||
total += list->len;
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
if (TEMP_FAILURE_RETRY (__writev (fd, iov, nlist)) == total)
|
||||
written = true;
|
||||
}
|
||||
|
||||
va_end (ap);
|
||||
|
||||
/* If we had no success writing the message, use syslog. */
|
||||
if (! written)
|
||||
vsyslog (LOG_ERR, fmt, ap_copy);
|
||||
|
||||
va_end (ap_copy);
|
||||
|
||||
if (do_abort()
|
||||
/* Kill the application. */
|
||||
abort ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__libc_fatal (message)
|
||||
const char *message;
|
||||
{
|
||||
__libc_message (1, "%s", message);
|
||||
}
|
||||
libc_hidden_def (__libc_fatal)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1993-1995,1997,2000,2002, 2003 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1993-1995,1997,2000,2002-2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -16,45 +16,143 @@
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sysdep.h>
|
||||
#include <string.h>
|
||||
#include <abort-instr.h>
|
||||
#include <sysdep.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syslog.h>
|
||||
#ifndef ABORT_INSTRUCTION
|
||||
/* No such instruction is available. */
|
||||
# define ABORT_INSTRUCTION
|
||||
#endif
|
||||
|
||||
/* Abort with an error message. */
|
||||
#include <not-cancel.h>
|
||||
|
||||
#ifdef FATAL_PREPARE_INCLUDE
|
||||
#include FATAL_PREPARE_INCLUDE
|
||||
#endif
|
||||
|
||||
struct str_list
|
||||
{
|
||||
const char *str;
|
||||
size_t len;
|
||||
struct str_list *next;
|
||||
};
|
||||
|
||||
|
||||
/* Abort with an error message. */
|
||||
void
|
||||
__libc_message (int do_abort, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_list ap_copy;
|
||||
int fd = -1;
|
||||
|
||||
va_start (ap, fmt);
|
||||
va_copy (ap_copy, ap);
|
||||
|
||||
#ifdef FATAL_PREPARE
|
||||
FATAL_PREPARE;
|
||||
#endif
|
||||
|
||||
/* Open a descriptor for /dev/tty unless the user explicitly
|
||||
requests errors on standard error. */
|
||||
const char *on_2 = __secure_getenv ("LIBC_FATAL_STDERR_");
|
||||
if (on_2 == NULL || *on_2 == '\0')
|
||||
fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
|
||||
|
||||
if (fd == -1)
|
||||
fd = STDERR_FILENO;
|
||||
|
||||
struct str_list *list = NULL;
|
||||
int nlist = 0;
|
||||
|
||||
const char *cp = fmt;
|
||||
while (*cp != '\0')
|
||||
{
|
||||
/* Find the next "%s" or the end of the string. */
|
||||
const char *next = cp;
|
||||
while (next[0] != '%' || next[1] != 's')
|
||||
{
|
||||
next = __strchrnul (next + 1, '%');
|
||||
|
||||
if (next[0] == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
/* Determine what to print. */
|
||||
const char *str;
|
||||
size_t len;
|
||||
if (cp[0] == '%' && cp[1] == 's')
|
||||
{
|
||||
str = va_arg (ap, const char *);
|
||||
len = strlen (str);
|
||||
cp += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
str = cp;
|
||||
len = next - cp;
|
||||
cp = next;
|
||||
}
|
||||
|
||||
struct str_list *newp = alloca (sizeof (struct str_list));
|
||||
newp->str = str;
|
||||
newp->len = len;
|
||||
newp->next = list;
|
||||
list = newp;
|
||||
++nlist;
|
||||
}
|
||||
|
||||
bool written = false;
|
||||
if (nlist > 0)
|
||||
{
|
||||
struct iovec *iov = alloca (nlist * sizeof (struct iovec));
|
||||
ssize_t total = 0;
|
||||
|
||||
for (int cnt = nlist - 1; cnt >= 0; --cnt)
|
||||
{
|
||||
iov[cnt].iov_base = (void *) list->str;
|
||||
iov[cnt].iov_len = list->len;
|
||||
total += list->len;
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
ssize_t cnt;
|
||||
do
|
||||
cnt = INTERNAL_SYSCALL (writev, err, 3, fd, iov, nlist);
|
||||
while (INTERNAL_SYSCALL_ERROR_P (cnt, err)
|
||||
&& INTERNAL_SYSCALL_ERRNO (cnt, err) == EINTR);
|
||||
|
||||
if (cnt == total)
|
||||
written = true;
|
||||
}
|
||||
|
||||
va_end (ap);
|
||||
|
||||
/* If we had no success writing the message, use syslog. */
|
||||
if (! written)
|
||||
vsyslog (LOG_ERR, fmt, ap_copy);
|
||||
|
||||
va_end (ap_copy);
|
||||
|
||||
if (do_abort)
|
||||
/* Terminate the process. */
|
||||
abort ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__libc_fatal (message)
|
||||
const char *message;
|
||||
{
|
||||
size_t len = strlen (message);
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
ssize_t count = INTERNAL_SYSCALL (write, err, 3, STDERR_FILENO,
|
||||
message, len);
|
||||
if (! INTERNAL_SYSCALL_ERROR_P (count, err))
|
||||
{
|
||||
message += count;
|
||||
len -= count;
|
||||
}
|
||||
else if (INTERNAL_SYSCALL_ERRNO (count, err) != EINTR)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Terminate the process. */
|
||||
_exit (127);
|
||||
|
||||
/* The previous call should never have returned. */
|
||||
while (1)
|
||||
/* Try for ever and ever. */
|
||||
ABORT_INSTRUCTION;
|
||||
__libc_message (1, "%s", message);
|
||||
}
|
||||
libc_hidden_def (__libc_fatal)
|
||||
|
Loading…
x
Reference in New Issue
Block a user