summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortdeval <>2004-08-05 21:55:21 +0000
committertdeval <>2004-08-05 21:55:21 +0000
commit3c4566ef1079a75ca935096218c75f551d8e26c7 (patch)
tree73365eb3ab2d80d60c8f31fc26e2b57e5febfc2c
parentc83fda0075d86da98f69b2e750005da6bf478117 (diff)
downloadopenbsd-3c4566ef1079a75ca935096218c75f551d8e26c7.tar.gz
openbsd-3c4566ef1079a75ca935096218c75f551d8e26c7.tar.bz2
openbsd-3c4566ef1079a75ca935096218c75f551d8e26c7.zip
- Remove the userland data limit check. It's mmap(2)'s job.
- When malloc_abort==0 (MALLOC_OPTIONS=a), don't abort in wrterror(). fine deraadt@
-rw-r--r--src/lib/libc/stdlib/malloc.c145
1 files changed, 108 insertions, 37 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index 6e5d60542c..aedb4c8f0c 100644
--- a/src/lib/libc/stdlib/malloc.c
+++ b/src/lib/libc/stdlib/malloc.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#if defined(LIBC_SCCS) && !defined(lint) 10#if defined(LIBC_SCCS) && !defined(lint)
11static char rcsid[] = "$OpenBSD: malloc.c,v 1.69 2004/08/04 19:12:53 tdeval Exp $"; 11static char rcsid[] = "$OpenBSD: malloc.c,v 1.70 2004/08/05 21:55:21 tdeval Exp $";
12#endif /* LIBC_SCCS and not lint */ 12#endif /* LIBC_SCCS and not lint */
13 13
14/* 14/*
@@ -424,7 +424,8 @@ wrterror(char *p)
424 malloc_dump(stderr); 424 malloc_dump(stderr);
425#endif /* MALLOC_STATS */ 425#endif /* MALLOC_STATS */
426 malloc_active--; 426 malloc_active--;
427 abort(); 427 if (malloc_abort)
428 abort();
428} 429}
429 430
430static void 431static void
@@ -533,8 +534,11 @@ map_pages(size_t pages)
533 pi->dirnum += PI_OFF(ptr2index(tail - 1)) + 1; 534 pi->dirnum += PI_OFF(ptr2index(tail - 1)) + 1;
534 } 535 }
535#ifdef MALLOC_EXTRA_SANITY 536#ifdef MALLOC_EXTRA_SANITY
536 if (PD_OFF(pi->dirnum) > pdi_mod || PD_IDX(pi->dirnum) > index) 537 if (PD_OFF(pi->dirnum) > pdi_mod || PD_IDX(pi->dirnum) > index) {
537 wrterror("(ES): pages directory overflow\n"); 538 wrterror("(ES): pages directory overflow\n");
539 errno = EFAULT;
540 return (NULL);
541 }
538#endif /* MALLOC_EXTRA_SANITY */ 542#endif /* MALLOC_EXTRA_SANITY */
539 if (index == pidx && pi != last_dir) { 543 if (index == pidx && pi != last_dir) {
540 prev_dir = last_dir; 544 prev_dir = last_dir;
@@ -640,8 +644,11 @@ malloc_init(void)
640 /* Allocate one page for the page directory */ 644 /* Allocate one page for the page directory */
641 page_dir = (struct pginfo **) MMAP(malloc_pagesize); 645 page_dir = (struct pginfo **) MMAP(malloc_pagesize);
642 646
643 if (page_dir == MAP_FAILED) 647 if (page_dir == MAP_FAILED) {
644 wrterror("mmap(2) failed, check limits\n"); 648 wrterror("mmap(2) failed, check limits\n");
649 errno = ENOMEM;
650 return;
651 }
645 652
646 pdi_off = (malloc_pagesize - sizeof(struct pdinfo)) & ~(malloc_minsize - 1); 653 pdi_off = (malloc_pagesize - sizeof(struct pdinfo)) & ~(malloc_minsize - 1);
647 pdi_mod = pdi_off / sizeof(struct pginfo *); 654 pdi_mod = pdi_off / sizeof(struct pginfo *);
@@ -685,39 +692,55 @@ malloc_pages(size_t size)
685 692
686 size = pageround(size) + malloc_guard; 693 size = pageround(size) + malloc_guard;
687 694
688 if (getrlimit(RLIMIT_DATA, &rl) == -1)
689 wrterror("process limits not available\n");
690 if (rl.rlim_cur != RLIM_INFINITY &&
691 size > ((size_t)rl.rlim_cur - malloc_used)) {
692 errno = ENOMEM;
693 return (NULL);
694 }
695
696 p = NULL; 695 p = NULL;
697 /* Look for free pages before asking for more */ 696 /* Look for free pages before asking for more */
698 for (pf = free_list.next; pf; pf = pf->next) { 697 for (pf = free_list.next; pf; pf = pf->next) {
699 698
700#ifdef MALLOC_EXTRA_SANITY 699#ifdef MALLOC_EXTRA_SANITY
701 if (pf->size & malloc_pagemask) 700 if (pf->size & malloc_pagemask) {
702 wrterror("(ES): junk length entry on free_list\n"); 701 wrterror("(ES): junk length entry on free_list\n");
703 if (!pf->size) 702 errno = EFAULT;
703 return (NULL);
704 }
705 if (!pf->size) {
704 wrterror("(ES): zero length entry on free_list\n"); 706 wrterror("(ES): zero length entry on free_list\n");
705 if (pf->page > (pf->page + pf->size)) 707 errno = EFAULT;
708 return (NULL);
709 }
710 if (pf->page > (pf->page + pf->size)) {
706 wrterror("(ES): sick entry on free_list\n"); 711 wrterror("(ES): sick entry on free_list\n");
707 if ((pi = pf->pdir) == NULL) 712 errno = EFAULT;
713 return (NULL);
714 }
715 if ((pi = pf->pdir) == NULL) {
708 wrterror("(ES): invalid page directory on free-list\n"); 716 wrterror("(ES): invalid page directory on free-list\n");
709 if ((pidx = PI_IDX(ptr2index(pf->page))) != PD_IDX(pi->dirnum)) 717 errno = EFAULT;
718 return (NULL);
719 }
720 if ((pidx = PI_IDX(ptr2index(pf->page))) != PD_IDX(pi->dirnum)) {
710 wrterror("(ES): directory index mismatch on free-list\n"); 721 wrterror("(ES): directory index mismatch on free-list\n");
722 errno = EFAULT;
723 return (NULL);
724 }
711 pd = pi->base; 725 pd = pi->base;
712 if (pd[PI_OFF(ptr2index(pf->page))] != MALLOC_FREE) 726 if (pd[PI_OFF(ptr2index(pf->page))] != MALLOC_FREE) {
713 wrterror("(ES): non-free first page on free-list\n"); 727 wrterror("(ES): non-free first page on free-list\n");
728 errno = EFAULT;
729 return (NULL);
730 }
714 pidx = PI_IDX(ptr2index((pf->page)+(pf->size))-1); 731 pidx = PI_IDX(ptr2index((pf->page)+(pf->size))-1);
715 for (pi=pf->pdir; pi!=NULL && PD_IDX(pi->dirnum)<pidx; pi=pi->next); 732 for (pi=pf->pdir; pi!=NULL && PD_IDX(pi->dirnum)<pidx; pi=pi->next);
716 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) 733 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) {
717 wrterror("(ES): last page not referenced in page directory\n"); 734 wrterror("(ES): last page not referenced in page directory\n");
735 errno = EFAULT;
736 return (NULL);
737 }
718 pd = pi->base; 738 pd = pi->base;
719 if (pd[PI_OFF(ptr2index((pf->page)+(pf->size))-1)] != MALLOC_FREE) 739 if (pd[PI_OFF(ptr2index((pf->page)+(pf->size))-1)] != MALLOC_FREE) {
720 wrterror("(ES): non-free last page on free-list\n"); 740 wrterror("(ES): non-free last page on free-list\n");
741 errno = EFAULT;
742 return (NULL);
743 }
721#endif /* MALLOC_EXTRA_SANITY */ 744#endif /* MALLOC_EXTRA_SANITY */
722 745
723 if (pf->size < size) 746 if (pf->size < size)
@@ -738,8 +761,11 @@ malloc_pages(size_t size)
738 pf->size -= size; 761 pf->size -= size;
739 pidx = PI_IDX(ptr2index(pf->page)); 762 pidx = PI_IDX(ptr2index(pf->page));
740 for (pi=pf->pdir; pi!=NULL && PD_IDX(pi->dirnum)<pidx; pi=pi->next); 763 for (pi=pf->pdir; pi!=NULL && PD_IDX(pi->dirnum)<pidx; pi=pi->next);
741 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) 764 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) {
742 wrterror("(ES): hole in directories\n"); 765 wrterror("(ES): hole in directories\n");
766 errno = EFAULT;
767 return (NULL);
768 }
743 tp = pf->pdir; 769 tp = pf->pdir;
744 pf->pdir = pi; 770 pf->pdir = pi;
745 pi = tp; 771 pi = tp;
@@ -753,8 +779,11 @@ malloc_pages(size_t size)
753 pidx = PD_IDX(pi->dirnum); 779 pidx = PD_IDX(pi->dirnum);
754 pd = pi->base; 780 pd = pi->base;
755 } 781 }
756 if (p != NULL && pd[PI_OFF(ptr2index(p))] != MALLOC_FREE) 782 if (p != NULL && pd[PI_OFF(ptr2index(p))] != MALLOC_FREE) {
757 wrterror("(ES): allocated non-free page on free-list\n"); 783 wrterror("(ES): allocated non-free page on free-list\n");
784 errno = EFAULT;
785 return (NULL);
786 }
758#endif /* MALLOC_EXTRA_SANITY */ 787#endif /* MALLOC_EXTRA_SANITY */
759 788
760 if (p != NULL && (malloc_guard || malloc_freeprot)) 789 if (p != NULL && (malloc_guard || malloc_freeprot))
@@ -772,8 +801,11 @@ malloc_pages(size_t size)
772 pidx = PI_IDX(index); 801 pidx = PI_IDX(index);
773 pdir_lookup(index, &pi); 802 pdir_lookup(index, &pi);
774#ifdef MALLOC_EXTRA_SANITY 803#ifdef MALLOC_EXTRA_SANITY
775 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) 804 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) {
776 wrterror("(ES): mapped pages not found in directory\n"); 805 wrterror("(ES): mapped pages not found in directory\n");
806 errno = EFAULT;
807 return (NULL);
808 }
777#endif /* MALLOC_EXTRA_SANITY */ 809#endif /* MALLOC_EXTRA_SANITY */
778 if (pi != last_dir) { 810 if (pi != last_dir) {
779 prev_dir = last_dir; 811 prev_dir = last_dir;
@@ -786,8 +818,11 @@ malloc_pages(size_t size)
786 pidx++; 818 pidx++;
787 pi = pi->next; 819 pi = pi->next;
788#ifdef MALLOC_EXTRA_SANITY 820#ifdef MALLOC_EXTRA_SANITY
789 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) 821 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) {
790 wrterror("(ES): hole in mapped pages directory\n"); 822 wrterror("(ES): hole in mapped pages directory\n");
823 errno = EFAULT;
824 return (NULL);
825 }
791#endif /* MALLOC_EXTRA_SANITY */ 826#endif /* MALLOC_EXTRA_SANITY */
792 pd = pi->base; 827 pd = pi->base;
793 } 828 }
@@ -798,8 +833,11 @@ malloc_pages(size_t size)
798 pidx++; 833 pidx++;
799 pi = pi->next; 834 pi = pi->next;
800#ifdef MALLOC_EXTRA_SANITY 835#ifdef MALLOC_EXTRA_SANITY
801 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) 836 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) {
802 wrterror("(ES): hole in mapped pages directory\n"); 837 wrterror("(ES): hole in mapped pages directory\n");
838 errno = EFAULT;
839 return (NULL);
840 }
803#endif /* MALLOC_EXTRA_SANITY */ 841#endif /* MALLOC_EXTRA_SANITY */
804 pd = pi->base; 842 pd = pi->base;
805 } 843 }
@@ -913,8 +951,11 @@ malloc_make_chunks(int bits)
913 pidx = PI_IDX(ptr2index(pp)); 951 pidx = PI_IDX(ptr2index(pp));
914 pdir_lookup(ptr2index(pp), &pi); 952 pdir_lookup(ptr2index(pp), &pi);
915#ifdef MALLOC_EXTRA_SANITY 953#ifdef MALLOC_EXTRA_SANITY
916 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) 954 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) {
917 wrterror("(ES): mapped pages not found in directory\n"); 955 wrterror("(ES): mapped pages not found in directory\n");
956 errno = EFAULT;
957 return (0);
958 }
918#endif /* MALLOC_EXTRA_SANITY */ 959#endif /* MALLOC_EXTRA_SANITY */
919 if (pi != last_dir) { 960 if (pi != last_dir) {
920 prev_dir = last_dir; 961 prev_dir = last_dir;
@@ -988,8 +1029,11 @@ malloc_bytes(size_t size)
988 k = 0; 1029 k = 0;
989 } 1030 }
990#ifdef MALLOC_EXTRA_SANITY 1031#ifdef MALLOC_EXTRA_SANITY
991 if (lp - bp->bits > (bp->total - 1) / MALLOC_BITS) 1032 if (lp - bp->bits > (bp->total - 1) / MALLOC_BITS) {
992 wrterror("chunk overflow\n"); 1033 wrterror("chunk overflow\n");
1034 errno = EFAULT;
1035 return (NULL);
1036 }
993#endif /* MALLOC_EXTRA_SANITY */ 1037#endif /* MALLOC_EXTRA_SANITY */
994 if (*lp & u) 1038 if (*lp & u)
995 i--; 1039 i--;
@@ -1081,8 +1125,11 @@ irealloc(void *ptr, size_t size)
1081 pidx = PI_IDX(index); 1125 pidx = PI_IDX(index);
1082 pdir_lookup(index, &pi); 1126 pdir_lookup(index, &pi);
1083#ifdef MALLOC_EXTRA_SANITY 1127#ifdef MALLOC_EXTRA_SANITY
1084 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) 1128 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) {
1085 wrterror("(ES): mapped pages not found in directory\n"); 1129 wrterror("(ES): mapped pages not found in directory\n");
1130 errno = EFAULT;
1131 return (NULL);
1132 }
1086#endif /* MALLOC_EXTRA_SANITY */ 1133#endif /* MALLOC_EXTRA_SANITY */
1087 if (pi != last_dir) { 1134 if (pi != last_dir) {
1088 prev_dir = last_dir; 1135 prev_dir = last_dir;
@@ -1212,8 +1259,11 @@ free_pages(void *ptr, u_long index, struct pginfo *info)
1212 pidx = PI_IDX(index); 1259 pidx = PI_IDX(index);
1213 pdir_lookup(index, &pi); 1260 pdir_lookup(index, &pi);
1214#ifdef MALLOC_EXTRA_SANITY 1261#ifdef MALLOC_EXTRA_SANITY
1215 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) 1262 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) {
1216 wrterror("(ES): mapped pages not found in directory\n"); 1263 wrterror("(ES): mapped pages not found in directory\n");
1264 errno = EFAULT;
1265 return;
1266 }
1217#endif /* MALLOC_EXTRA_SANITY */ 1267#endif /* MALLOC_EXTRA_SANITY */
1218 1268
1219 spi = pi; /* Save page index for start of region. */ 1269 spi = pi; /* Save page index for start of region. */
@@ -1247,8 +1297,11 @@ free_pages(void *ptr, u_long index, struct pginfo *info)
1247 malloc_used -= l; 1297 malloc_used -= l;
1248 if (malloc_guard) { 1298 if (malloc_guard) {
1249#ifdef MALLOC_EXTRA_SANITY 1299#ifdef MALLOC_EXTRA_SANITY
1250 if (pi == NULL || PD_IDX(pi->dirnum) != PI_IDX(index+i)) 1300 if (pi == NULL || PD_IDX(pi->dirnum) != PI_IDX(index+i)) {
1251 wrterror("(ES): hole in mapped pages directory\n"); 1301 wrterror("(ES): hole in mapped pages directory\n");
1302 errno = EFAULT;
1303 return;
1304 }
1252#endif /* MALLOC_EXTRA_SANITY */ 1305#endif /* MALLOC_EXTRA_SANITY */
1253 pd[PI_OFF(index+i)] = MALLOC_FREE; 1306 pd[PI_OFF(index+i)] = MALLOC_FREE;
1254 l += malloc_guard; 1307 l += malloc_guard;
@@ -1320,6 +1373,8 @@ free_pages(void *ptr, u_long index, struct pginfo *info)
1320 px = NULL; 1373 px = NULL;
1321 } else { 1374 } else {
1322 wrterror("freelist is destroyed\n"); 1375 wrterror("freelist is destroyed\n");
1376 errno = EFAULT;
1377 return;
1323 } 1378 }
1324 } 1379 }
1325 1380
@@ -1360,8 +1415,11 @@ free_pages(void *ptr, u_long index, struct pginfo *info)
1360 if (pd[PI_OFF(i)] != MALLOC_NOT_MINE) { 1415 if (pd[PI_OFF(i)] != MALLOC_NOT_MINE) {
1361 pd[PI_OFF(i)] = MALLOC_NOT_MINE; 1416 pd[PI_OFF(i)] = MALLOC_NOT_MINE;
1362#ifdef MALLOC_EXTRA_SANITY 1417#ifdef MALLOC_EXTRA_SANITY
1363 if (!PD_OFF(pi->dirnum)) 1418 if (!PD_OFF(pi->dirnum)) {
1364 wrterror("(ES): pages directory underflow\n"); 1419 wrterror("(ES): pages directory underflow\n");
1420 errno = EFAULT;
1421 return;
1422 }
1365#endif /* MALLOC_EXTRA_SANITY */ 1423#endif /* MALLOC_EXTRA_SANITY */
1366 pi->dirnum--; 1424 pi->dirnum--;
1367 } 1425 }
@@ -1452,8 +1510,11 @@ free_bytes(void *ptr, int index, struct pginfo *info)
1452 while (*mp != info) { 1510 while (*mp != info) {
1453 mp = &((*mp)->next); 1511 mp = &((*mp)->next);
1454#ifdef MALLOC_EXTRA_SANITY 1512#ifdef MALLOC_EXTRA_SANITY
1455 if (!*mp) 1513 if (!*mp) {
1456 wrterror("(ES): Not on queue\n"); 1514 wrterror("(ES): Not on queue\n");
1515 errno = EFAULT;
1516 return;
1517 }
1457#endif /* MALLOC_EXTRA_SANITY */ 1518#endif /* MALLOC_EXTRA_SANITY */
1458 } 1519 }
1459 *mp = info->next; 1520 *mp = info->next;
@@ -1462,8 +1523,11 @@ free_bytes(void *ptr, int index, struct pginfo *info)
1462 pidx = PI_IDX(ptr2index(info->page)); 1523 pidx = PI_IDX(ptr2index(info->page));
1463 pdir_lookup(ptr2index(info->page), &pi); 1524 pdir_lookup(ptr2index(info->page), &pi);
1464#ifdef MALLOC_EXTRA_SANITY 1525#ifdef MALLOC_EXTRA_SANITY
1465 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) 1526 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) {
1466 wrterror("(ES): mapped pages not found in directory\n"); 1527 wrterror("(ES): mapped pages not found in directory\n");
1528 errno = EFAULT;
1529 return;
1530 }
1467#endif /* MALLOC_EXTRA_SANITY */ 1531#endif /* MALLOC_EXTRA_SANITY */
1468 if (pi != last_dir) { 1532 if (pi != last_dir) {
1469 prev_dir = last_dir; 1533 prev_dir = last_dir;
@@ -1522,8 +1586,11 @@ ifree(void *ptr)
1522 pidx = PI_IDX(index); 1586 pidx = PI_IDX(index);
1523 pdir_lookup(index, &pi); 1587 pdir_lookup(index, &pi);
1524#ifdef MALLOC_EXTRA_SANITY 1588#ifdef MALLOC_EXTRA_SANITY
1525 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) 1589 if (pi == NULL || PD_IDX(pi->dirnum) != pidx) {
1526 wrterror("(ES): mapped pages not found in directory\n"); 1590 wrterror("(ES): mapped pages not found in directory\n");
1591 errno = EFAULT;
1592 return;
1593 }
1527#endif /* MALLOC_EXTRA_SANITY */ 1594#endif /* MALLOC_EXTRA_SANITY */
1528 if (pi != last_dir) { 1595 if (pi != last_dir) {
1529 prev_dir = last_dir; 1596 prev_dir = last_dir;
@@ -1577,8 +1644,10 @@ malloc(size_t size)
1577 UTRACE(0, size, r); 1644 UTRACE(0, size, r);
1578 malloc_active--; 1645 malloc_active--;
1579 _MALLOC_UNLOCK(); 1646 _MALLOC_UNLOCK();
1580 if (malloc_xmalloc && r == NULL) 1647 if (malloc_xmalloc && r == NULL) {
1581 wrterror("out of memory\n"); 1648 wrterror("out of memory\n");
1649 errno = ENOMEM;
1650 }
1582 return (r); 1651 return (r);
1583} 1652}
1584 1653
@@ -1617,7 +1686,9 @@ realloc(void *ptr, size_t size)
1617 UTRACE(ptr, size, r); 1686 UTRACE(ptr, size, r);
1618 malloc_active--; 1687 malloc_active--;
1619 _MALLOC_UNLOCK(); 1688 _MALLOC_UNLOCK();
1620 if (malloc_xmalloc && r == NULL) 1689 if (malloc_xmalloc && r == NULL) {
1621 wrterror("out of memory\n"); 1690 wrterror("out of memory\n");
1691 errno = ENOMEM;
1692 }
1622 return (r); 1693 return (r);
1623} 1694}