From owner-svn-src-head@freebsd.org Tue Aug 20 16:07:18 2019 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 2D0DBD52B5; Tue, 20 Aug 2019 16:07:18 +0000 (UTC) (envelope-from brooks@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 46CbKL0QDFz4VhX; Tue, 20 Aug 2019 16:07:18 +0000 (UTC) (envelope-from brooks@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id E14835B4E; Tue, 20 Aug 2019 16:07:17 +0000 (UTC) (envelope-from brooks@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x7KG7H8l001336; Tue, 20 Aug 2019 16:07:17 GMT (envelope-from brooks@FreeBSD.org) Received: (from brooks@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x7KG7HOb001335; Tue, 20 Aug 2019 16:07:17 GMT (envelope-from brooks@FreeBSD.org) Message-Id: <201908201607.x7KG7HOb001335@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: brooks set sender to brooks@FreeBSD.org using -f From: Brooks Davis Date: Tue, 20 Aug 2019 16:07:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r351251 - head/libexec/rtld-elf X-SVN-Group: head X-SVN-Commit-Author: brooks X-SVN-Commit-Paths: head/libexec/rtld-elf X-SVN-Commit-Revision: 351251 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Aug 2019 16:07:18 -0000 Author: brooks Date: Tue Aug 20 16:07:17 2019 New Revision: 351251 URL: https://svnweb.freebsd.org/changeset/base/351251 Log: Remove some compatability with Seventh Edition UNIX realloc(). In Seventh Edition UNIX, the last pointer passed to free() was guaranteed to not actually have been freed allowing memory to be "compacted" via the following pattern: free(foo); foo = realloc(foo, newsize); Further, Andrew Koenig reports in "C Traps and Pitfalls" that the original realloc() implementation required this pattern. The C standard is clear that this is Undefined Behavior. Modern allocators don't support it and no portable code could rely on it so remove this support. Note: the removed implementation contains an off-by-one error and if an item isn't found on the freelist, then twice as much memory as the largest possible allocation will be copied. Reviewed by: kib, imp Obtained from: CheriBSD Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D21296 Modified: head/libexec/rtld-elf/rtld_malloc.c Modified: head/libexec/rtld-elf/rtld_malloc.c ============================================================================== --- head/libexec/rtld-elf/rtld_malloc.c Tue Aug 20 15:14:32 2019 (r351250) +++ head/libexec/rtld-elf/rtld_malloc.c Tue Aug 20 16:07:17 2019 (r351251) @@ -85,7 +85,6 @@ union overhead { static void morecore(int bucket); static int morepages(int n); -static int findbucket(union overhead *freep, int srchlen); #define MAGIC 0xef /* magic # on accounting info */ @@ -248,19 +247,6 @@ __crt_free(void *cp) nextf[size] = op; } -/* - * When a program attempts "storage compaction" as mentioned in the - * old malloc man page, it realloc's an already freed block. Usually - * this is the last block it freed; occasionally it might be farther - * back. We have to search all the free lists for the block in order - * to determine its bucket: 1st we make one pass through the lists - * checking only the first block in each; if that fails we search - * ``realloc_srchlen'' blocks in each list for a match (the variable - * is extern so the caller can modify it). If that fails we just copy - * however many bytes was given to realloc() and hope it's not huge. - */ -static int realloc_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */ - void * __crt_realloc(void *cp, size_t nbytes) { @@ -268,78 +254,33 @@ __crt_realloc(void *cp, size_t nbytes) int i; union overhead *op; char *res; - int was_alloced = 0; if (cp == NULL) return (__crt_malloc(nbytes)); op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); - if (op->ov_magic == MAGIC) { - was_alloced++; - i = op->ov_index; - } else { - /* - * Already free, doing "compaction". - * - * Search for the old block of memory on the - * free list. First, check the most common - * case (last element free'd), then (this failing) - * the last ``realloc_srchlen'' items free'd. - * If all lookups fail, then assume the size of - * the memory block being realloc'd is the - * largest possible (so that all "nbytes" of new - * memory are copied into). Note that this could cause - * a memory fault if the old area was tiny, and the moon - * is gibbous. However, that is very unlikely. - */ - if ((i = findbucket(op, 1)) < 0 && - (i = findbucket(op, realloc_srchlen)) < 0) - i = NBUCKETS; - } + if (op->ov_magic != MAGIC) + return (NULL); /* Double-free or bad argument */ + i = op->ov_index; onb = 1 << (i + 3); if (onb < (u_int)pagesz) onb -= sizeof(*op); else onb += pagesz - sizeof(*op); /* avoid the copy if same size block */ - if (was_alloced) { - if (i) { - i = 1 << (i + 2); - if (i < pagesz) - i -= sizeof(*op); - else - i += pagesz - sizeof(*op); - } - if (nbytes <= onb && nbytes > (size_t)i) - return (cp); - __crt_free(cp); + if (i != 0) { + i = 1 << (i + 2); + if (i < pagesz) + i -= sizeof(*op); + else + i += pagesz - sizeof(*op); } + if (nbytes <= onb && nbytes > (size_t)i) + return (cp); if ((res = __crt_malloc(nbytes)) == NULL) return (NULL); - if (cp != res) /* common optimization if "compacting" */ - bcopy(cp, res, (nbytes < onb) ? nbytes : onb); + bcopy(cp, res, (nbytes < onb) ? nbytes : onb); + __crt_free(cp); return (res); -} - -/* - * Search ``srchlen'' elements of each free list for a block whose - * header starts at ``freep''. If srchlen is -1 search the whole list. - * Return bucket number, or -1 if not found. - */ -static int -findbucket(union overhead *freep, int srchlen) -{ - union overhead *p; - int i, j; - - for (i = 0; i < NBUCKETS; i++) { - j = 0; - for (p = nextf[i]; p && j != srchlen; p = p->ov_next) { - if (p == freep) - return (i); - j++; - } - } - return (-1); } static int