Changeset 988 for vendor/current/lib/talloc/testsuite.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/lib/talloc/testsuite.c
r746 r988 28 28 #include <talloc.h> 29 29 30 #ifdef HAVE_PTHREAD 31 #include <pthread.h> 32 #endif 33 34 #include <unistd.h> 35 #include <sys/wait.h> 36 30 37 #include "talloc_testsuite.h" 31 38 … … 57 64 return false; \ 58 65 } 59 60 #if _SAMBA_BUILD_==361 #ifdef malloc62 #undef malloc63 #endif64 #ifdef strdup65 #undef strdup66 #endif67 #endif68 66 69 67 #define CHECK_SIZE(test, ptr, tsize) do { \ … … 151 149 CHECK_BLOCKS("ref1", p1, 5); 152 150 CHECK_BLOCKS("ref1", p2, 1); 151 CHECK_BLOCKS("ref1", ref, 1); 153 152 CHECK_BLOCKS("ref1", r1, 2); 154 153 … … 259 258 CHECK_BLOCKS("ref3", p2, 2); 260 259 CHECK_BLOCKS("ref3", r1, 1); 260 CHECK_BLOCKS("ref3", ref, 1); 261 261 262 262 fprintf(stderr, "Freeing p1\n"); … … 301 301 CHECK_BLOCKS("ref4", p1, 5); 302 302 CHECK_BLOCKS("ref4", p2, 1); 303 CHECK_BLOCKS("ref4", ref, 1); 303 304 CHECK_BLOCKS("ref4", r1, 2); 304 305 … … 351 352 CHECK_BLOCKS("unlink", p1, 7); 352 353 CHECK_BLOCKS("unlink", p2, 1); 354 CHECK_BLOCKS("unlink", ref, 1); 353 355 CHECK_BLOCKS("unlink", r1, 2); 354 356 … … 419 421 torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo", 420 422 "failed: wrong name after talloc_set_name(my name is foo)"); 423 torture_assert_str_equal("misc", talloc_get_name(p1), name, 424 "failed: wrong name after talloc_set_name(my name is foo)"); 421 425 CHECK_BLOCKS("misc", p1, 2); 422 426 CHECK_BLOCKS("misc", root, 3); … … 627 631 el2 = talloc(el1->list2, struct el2); 628 632 el2 = talloc(el1->list3, struct el2); 633 (void)el2; 629 634 630 635 el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100); … … 839 844 p2 = talloc_strdup(p1, "foo bar"); 840 845 p3 = talloc_size(p1, 300); 846 (void)p2; 847 (void)p3; 841 848 talloc_free(p1); 842 849 } … … 858 865 p2 = talloc_strdup(p1, "foo bar"); 859 866 p3 = talloc_size(p1, 300); 860 talloc_free_children(ctx); 867 (void)p2; 868 (void)p3; 869 talloc_free(p1); 861 870 } 862 871 count += 3 * loop; … … 980 989 } 981 990 991 struct new_parent { 992 void *new_parent; 993 char val[20]; 994 }; 995 996 static int reparenting_destructor(struct new_parent *np) 997 { 998 talloc_set_destructor(np, NULL); 999 (void)talloc_move(np->new_parent, &np); 1000 return -1; 1001 } 1002 1003 static bool test_free_parent_reparent_child(void) 1004 { 1005 void *top = talloc_new(NULL); 1006 char *level1; 1007 char *alternate_level1; 1008 char *level2; 1009 struct new_parent *level3; 1010 1011 printf("test: free_parent_reparent_child\n# " 1012 "TALLOC FREE PARENT REPARENT CHILD\n"); 1013 1014 level1 = talloc_strdup(top, "level1"); 1015 alternate_level1 = talloc_strdup(top, "alternate_level1"); 1016 level2 = talloc_strdup(level1, "level2"); 1017 level3 = talloc(level2, struct new_parent); 1018 level3->new_parent = alternate_level1; 1019 memset(level3->val, 'x', sizeof(level3->val)); 1020 1021 talloc_set_destructor(level3, reparenting_destructor); 1022 talloc_free(level1); 1023 1024 CHECK_PARENT("free_parent_reparent_child", 1025 level3, alternate_level1); 1026 1027 talloc_free(top); 1028 1029 printf("success: free_parent_reparent_child\n"); 1030 return true; 1031 } 1032 1033 static bool test_free_parent_reparent_child_in_pool(void) 1034 { 1035 void *top = talloc_new(NULL); 1036 char *level1; 1037 char *alternate_level1; 1038 char *level2; 1039 void *pool; 1040 struct new_parent *level3; 1041 1042 printf("test: free_parent_reparent_child_in_pool\n# " 1043 "TALLOC FREE PARENT REPARENT CHILD IN POOL\n"); 1044 1045 pool = talloc_pool(top, 1024); 1046 level1 = talloc_strdup(pool, "level1"); 1047 alternate_level1 = talloc_strdup(top, "alternate_level1"); 1048 level2 = talloc_strdup(level1, "level2"); 1049 level3 = talloc(level2, struct new_parent); 1050 level3->new_parent = alternate_level1; 1051 memset(level3->val, 'x', sizeof(level3->val)); 1052 1053 talloc_set_destructor(level3, reparenting_destructor); 1054 talloc_free(level1); 1055 talloc_set_destructor(level3, NULL); 1056 1057 CHECK_PARENT("free_parent_reparent_child_in_pool", 1058 level3, alternate_level1); 1059 1060 /* Even freeing alternate_level1 should leave pool alone. */ 1061 talloc_free(alternate_level1); 1062 talloc_free(top); 1063 1064 printf("success: free_parent_reparent_child_in_pool\n"); 1065 return true; 1066 } 1067 1068 982 1069 static bool test_talloc_ptrtype(void) 983 1070 { … … 1277 1364 } 1278 1365 1366 static bool test_pool_nest(void) 1367 { 1368 void *p1, *p2, *p3; 1369 void *e = talloc_new(NULL); 1370 1371 p1 = talloc_pool(NULL, 1024); 1372 torture_assert("talloc_pool", p1 != NULL, "failed"); 1373 1374 p2 = talloc_pool(p1, 500); 1375 torture_assert("talloc_pool", p2 != NULL, "failed"); 1376 1377 p3 = talloc_size(p2, 10); 1378 1379 talloc_steal(e, p3); 1380 1381 talloc_free(p2); 1382 1383 talloc_free(p3); 1384 1385 talloc_free(p1); 1386 1387 return true; 1388 } 1389 1390 struct pooled { 1391 char *s1; 1392 char *s2; 1393 char *s3; 1394 }; 1395 1396 static bool test_pooled_object(void) 1397 { 1398 struct pooled *p; 1399 const char *s1 = "hello"; 1400 const char *s2 = "world"; 1401 const char *s3 = ""; 1402 1403 p = talloc_pooled_object(NULL, struct pooled, 3, 1404 strlen(s1)+strlen(s2)+strlen(s3)+3); 1405 1406 if (talloc_get_size(p) != sizeof(struct pooled)) { 1407 return false; 1408 } 1409 1410 p->s1 = talloc_strdup(p, s1); 1411 1412 TALLOC_FREE(p->s1); 1413 p->s1 = talloc_strdup(p, s2); 1414 TALLOC_FREE(p->s1); 1415 1416 p->s1 = talloc_strdup(p, s1); 1417 p->s2 = talloc_strdup(p, s2); 1418 p->s3 = talloc_strdup(p, s3); 1419 1420 TALLOC_FREE(p); 1421 return true; 1422 } 1423 1279 1424 static bool test_free_ref_null_context(void) 1280 1425 { … … 1325 1470 { 1326 1471 void *root; 1327 const char *p1, *p2, *name, *name2; 1472 char *p1, *p2; 1473 const char *name, *name2; 1328 1474 1329 1475 talloc_enable_null_tracking(); … … 1331 1477 p1 = talloc_strdup(root, "foo1"); 1332 1478 p2 = talloc_strdup(p1, "foo2"); 1479 (void)p2; 1333 1480 1334 1481 talloc_set_name(p1, "%s", "testname"); … … 1355 1502 /* but this does */ 1356 1503 talloc_free_children(p1); 1504 (void)name2; 1357 1505 torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname2") == 0, 1358 1506 "wrong name"); … … 1364 1512 } 1365 1513 1514 static bool test_memlimit(void) 1515 { 1516 void *root; 1517 char *l1, *l2, *l3, *l4, *l5, *t; 1518 char *pool; 1519 int i; 1520 1521 printf("test: memlimit\n# MEMORY LIMITS\n"); 1522 1523 printf("==== talloc_new(NULL)\n"); 1524 root = talloc_new(NULL); 1525 1526 talloc_report_full(root, stdout); 1527 1528 printf("==== talloc_size(root, 2048)\n"); 1529 l1 = talloc_size(root, 2048); 1530 torture_assert("memlimit", l1 != NULL, 1531 "failed: alloc should not fail due to memory limit\n"); 1532 1533 talloc_report_full(root, stdout); 1534 1535 printf("==== talloc_free(l1)\n"); 1536 talloc_free(l1); 1537 1538 talloc_report_full(root, stdout); 1539 1540 printf("==== talloc_strdup(root, level 1)\n"); 1541 l1 = talloc_strdup(root, "level 1"); 1542 torture_assert("memlimit", l1 != NULL, 1543 "failed: alloc should not fail due to memory limit\n"); 1544 1545 talloc_report_full(root, stdout); 1546 1547 printf("==== talloc_set_memlimit(l1, 2048)\n"); 1548 torture_assert("memlimit", talloc_set_memlimit(l1, 2048) == 0, 1549 "failed: setting memlimit should never fail\n"); 1550 1551 talloc_report_full(root, stdout); 1552 1553 printf("==== talloc_size(root, 2048)\n"); 1554 l2 = talloc_size(l1, 2048); 1555 torture_assert("memlimit", l2 == NULL, 1556 "failed: alloc should fail due to memory limit\n"); 1557 1558 talloc_report_full(root, stdout); 1559 1560 printf("==== talloc_strdup(l1, level 2)\n"); 1561 l2 = talloc_strdup(l1, "level 2"); 1562 torture_assert("memlimit", l2 != NULL, 1563 "failed: alloc should not fail due to memory limit\n"); 1564 1565 talloc_report_full(root, stdout); 1566 1567 printf("==== talloc_free(l2)\n"); 1568 talloc_free(l2); 1569 1570 talloc_report_full(root, stdout); 1571 1572 printf("==== talloc_size(NULL, 2048)\n"); 1573 l2 = talloc_size(NULL, 2048); 1574 1575 talloc_report_full(root, stdout); 1576 1577 printf("==== talloc_steal(l1, l2)\n"); 1578 talloc_steal(l1, l2); 1579 1580 talloc_report_full(root, stdout); 1581 1582 printf("==== talloc_strdup(l2, level 3)\n"); 1583 l3 = talloc_strdup(l2, "level 3"); 1584 torture_assert("memlimit", l3 == NULL, 1585 "failed: alloc should fail due to memory limit\n"); 1586 1587 talloc_report_full(root, stdout); 1588 1589 printf("==== talloc_free(l2)\n"); 1590 talloc_free(l2); 1591 1592 talloc_report_full(root, stdout); 1593 1594 printf("==== talloc_strdup(NULL, level 2)\n"); 1595 l2 = talloc_strdup(NULL, "level 2"); 1596 talloc_steal(l1, l2); 1597 1598 talloc_report_full(root, stdout); 1599 1600 printf("==== talloc_strdup(l2, level 3)\n"); 1601 l3 = talloc_strdup(l2, "level 3"); 1602 torture_assert("memlimit", l3 != NULL, 1603 "failed: alloc should not fail due to memory limit\n"); 1604 1605 talloc_report_full(root, stdout); 1606 1607 printf("==== talloc_set_memlimit(l3, 1024)\n"); 1608 torture_assert("memlimit", talloc_set_memlimit(l3, 1024) == 0, 1609 "failed: setting memlimit should never fail\n"); 1610 1611 talloc_report_full(root, stdout); 1612 1613 printf("==== talloc_strdup(l3, level 4)\n"); 1614 l4 = talloc_strdup(l3, "level 4"); 1615 torture_assert("memlimit", l4 != NULL, 1616 "failed: alloc should not fail due to memory limit\n"); 1617 1618 talloc_report_full(root, stdout); 1619 1620 printf("==== talloc_set_memlimit(l4, 512)\n"); 1621 torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0, 1622 "failed: setting memlimit should never fail\n"); 1623 1624 talloc_report_full(root, stdout); 1625 1626 printf("==== talloc_strdup(l4, level 5)\n"); 1627 l5 = talloc_strdup(l4, "level 5"); 1628 torture_assert("memlimit", l5 != NULL, 1629 "failed: alloc should not fail due to memory limit\n"); 1630 1631 talloc_report_full(root, stdout); 1632 1633 printf("==== talloc_realloc(NULL, l5, char, 600)\n"); 1634 t = talloc_realloc(NULL, l5, char, 600); 1635 torture_assert("memlimit", t == NULL, 1636 "failed: alloc should fail due to memory limit\n"); 1637 1638 talloc_report_full(root, stdout); 1639 1640 printf("==== talloc_realloc(NULL, l5, char, 5)\n"); 1641 l5 = talloc_realloc(NULL, l5, char, 5); 1642 torture_assert("memlimit", l5 != NULL, 1643 "failed: alloc should not fail due to memory limit\n"); 1644 1645 talloc_report_full(root, stdout); 1646 1647 printf("==== talloc_strdup(l3, level 4)\n"); 1648 l4 = talloc_strdup(l3, "level 4"); 1649 torture_assert("memlimit", l4 != NULL, 1650 "failed: alloc should not fail due to memory limit\n"); 1651 1652 talloc_report_full(root, stdout); 1653 1654 printf("==== talloc_set_memlimit(l4, 512)\n"); 1655 torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0, 1656 "failed: setting memlimit should never fail\n"); 1657 1658 talloc_report_full(root, stdout); 1659 1660 printf("==== talloc_strdup(l4, level 5)\n"); 1661 l5 = talloc_strdup(l4, "level 5"); 1662 torture_assert("memlimit", l5 != NULL, 1663 "failed: alloc should not fail due to memory limit\n"); 1664 1665 talloc_report_full(root, stdout); 1666 1667 printf("==== Make new temp context and steal l5\n"); 1668 t = talloc_new(root); 1669 talloc_steal(t, l5); 1670 1671 talloc_report_full(root, stdout); 1672 1673 printf("==== talloc_size(t, 2048)\n"); 1674 l1 = talloc_size(t, 2048); 1675 torture_assert("memlimit", l1 != NULL, 1676 "failed: alloc should not fail due to memory limit\n"); 1677 1678 talloc_report_full(root, stdout); 1679 talloc_free(root); 1680 1681 /* Test memlimits with pools. */ 1682 pool = talloc_pool(NULL, 10*1024); 1683 torture_assert("memlimit", pool != NULL, 1684 "failed: alloc should not fail due to memory limit\n"); 1685 talloc_set_memlimit(pool, 10*1024); 1686 for (i = 0; i < 9; i++) { 1687 l1 = talloc_size(pool, 1024); 1688 torture_assert("memlimit", l1 != NULL, 1689 "failed: alloc should not fail due to memory limit\n"); 1690 } 1691 /* The next alloc should fail. */ 1692 l2 = talloc_size(pool, 1024); 1693 torture_assert("memlimit", l2 == NULL, 1694 "failed: alloc should fail due to memory limit\n"); 1695 1696 /* Moving one of the children shouldn't change the limit, 1697 as it's still inside the pool. */ 1698 root = talloc_new(NULL); 1699 talloc_steal(root, l1); 1700 l2 = talloc_size(pool, 1024); 1701 torture_assert("memlimit", l2 == NULL, 1702 "failed: alloc should fail due to memory limit\n"); 1703 1704 talloc_free(pool); 1705 talloc_free(root); 1706 printf("success: memlimit\n"); 1707 1708 return true; 1709 } 1710 1711 #ifdef HAVE_PTHREAD 1712 1713 #define NUM_THREADS 100 1714 1715 /* Sync variables. */ 1716 static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; 1717 static pthread_cond_t condvar = PTHREAD_COND_INITIALIZER; 1718 static void *intermediate_ptr; 1719 1720 /* Subthread. */ 1721 static void *thread_fn(void *arg) 1722 { 1723 int ret; 1724 const char *ctx_name = (const char *)arg; 1725 void *sub_ctx = NULL; 1726 /* 1727 * Do stuff that creates a new talloc hierarchy in 1728 * this thread. 1729 */ 1730 void *top_ctx = talloc_named_const(NULL, 0, "top"); 1731 if (top_ctx == NULL) { 1732 return NULL; 1733 } 1734 sub_ctx = talloc_named_const(top_ctx, 100, ctx_name); 1735 if (sub_ctx == NULL) { 1736 return NULL; 1737 } 1738 1739 /* 1740 * Now transfer a pointer from our hierarchy 1741 * onto the intermediate ptr. 1742 */ 1743 ret = pthread_mutex_lock(&mtx); 1744 if (ret != 0) { 1745 talloc_free(top_ctx); 1746 return NULL; 1747 } 1748 /* Wait for intermediate_ptr to be free. */ 1749 while (intermediate_ptr != NULL) { 1750 ret = pthread_cond_wait(&condvar, &mtx); 1751 if (ret != 0) { 1752 talloc_free(top_ctx); 1753 pthread_mutex_unlock(&mtx); 1754 return NULL; 1755 } 1756 } 1757 1758 /* and move our memory onto it from our toplevel hierarchy. */ 1759 intermediate_ptr = talloc_move(NULL, &sub_ctx); 1760 1761 /* Tell the main thread it's ready for pickup. */ 1762 pthread_cond_broadcast(&condvar); 1763 pthread_mutex_unlock(&mtx); 1764 1765 talloc_free(top_ctx); 1766 return NULL; 1767 } 1768 1769 /* Main thread. */ 1770 static bool test_pthread_talloc_passing(void) 1771 { 1772 int i; 1773 int ret; 1774 char str_array[NUM_THREADS][20]; 1775 pthread_t thread_id; 1776 void *mem_ctx; 1777 1778 /* 1779 * Important ! Null tracking breaks threaded talloc. 1780 * It *must* be turned off. 1781 */ 1782 talloc_disable_null_tracking(); 1783 1784 printf("test: pthread_talloc_passing\n# PTHREAD TALLOC PASSING\n"); 1785 1786 /* Main thread toplevel context. */ 1787 mem_ctx = talloc_named_const(NULL, 0, "toplevel"); 1788 if (mem_ctx == NULL) { 1789 printf("failed to create toplevel context\n"); 1790 return false; 1791 } 1792 1793 /* 1794 * Spin off NUM_THREADS threads. 1795 * They will use their own toplevel contexts. 1796 */ 1797 for (i = 0; i < NUM_THREADS; i++) { 1798 (void)snprintf(str_array[i], 1799 20, 1800 "thread:%d", 1801 i); 1802 if (str_array[i] == NULL) { 1803 printf("snprintf %d failed\n", i); 1804 return false; 1805 } 1806 ret = pthread_create(&thread_id, 1807 NULL, 1808 thread_fn, 1809 str_array[i]); 1810 if (ret != 0) { 1811 printf("failed to create thread %d (%d)\n", i, ret); 1812 return false; 1813 } 1814 } 1815 1816 printf("Created %d threads\n", NUM_THREADS); 1817 1818 /* Now wait for NUM_THREADS transfers of the talloc'ed memory. */ 1819 for (i = 0; i < NUM_THREADS; i++) { 1820 ret = pthread_mutex_lock(&mtx); 1821 if (ret != 0) { 1822 printf("pthread_mutex_lock %d failed (%d)\n", i, ret); 1823 talloc_free(mem_ctx); 1824 return false; 1825 } 1826 1827 /* Wait for intermediate_ptr to have our data. */ 1828 while (intermediate_ptr == NULL) { 1829 ret = pthread_cond_wait(&condvar, &mtx); 1830 if (ret != 0) { 1831 printf("pthread_cond_wait %d failed (%d)\n", i, 1832 ret); 1833 talloc_free(mem_ctx); 1834 pthread_mutex_unlock(&mtx); 1835 return false; 1836 } 1837 } 1838 1839 /* and move it onto our toplevel hierarchy. */ 1840 (void)talloc_move(mem_ctx, &intermediate_ptr); 1841 1842 /* Tell the sub-threads we're ready for another. */ 1843 pthread_cond_broadcast(&condvar); 1844 pthread_mutex_unlock(&mtx); 1845 } 1846 1847 CHECK_SIZE("pthread_talloc_passing", mem_ctx, NUM_THREADS * 100); 1848 #if 1 1849 /* Dump the hierarchy. */ 1850 talloc_report(mem_ctx, stdout); 1851 #endif 1852 talloc_free(mem_ctx); 1853 printf("success: pthread_talloc_passing\n"); 1854 return true; 1855 } 1856 #endif 1857 1858 static void test_magic_protection_abort(const char *reason) 1859 { 1860 /* exit with errcode 42 to communicate successful test to the parent process */ 1861 if (strcmp(reason, "Bad talloc magic value - unknown value") == 0) { 1862 _exit(42); 1863 } else { 1864 printf("talloc aborted for an unexpected reason\n"); 1865 } 1866 } 1867 1868 static bool test_magic_protection(void) 1869 { 1870 void *pool = talloc_pool(NULL, 1024); 1871 int *p1, *p2; 1872 pid_t pid; 1873 int exit_status; 1874 1875 printf("test: magic_protection\n"); 1876 p1 = talloc(pool, int); 1877 p2 = talloc(pool, int); 1878 1879 /* To avoid complaints from the compiler assign values to the p1 & p2. */ 1880 *p1 = 6; 1881 *p2 = 9; 1882 1883 pid = fork(); 1884 if (pid == 0) { 1885 talloc_set_abort_fn(test_magic_protection_abort); 1886 1887 /* 1888 * Simulate a security attack 1889 * by triggering a buffer overflow in memset to overwrite the 1890 * constructor in the next pool chunk. 1891 * 1892 * Real attacks would attempt to set a real destructor. 1893 */ 1894 memset(p1, '\0', 32); 1895 1896 /* Then the attack takes effect when the memory's freed. */ 1897 talloc_free(pool); 1898 1899 /* Never reached. Make compilers happy */ 1900 return true; 1901 } 1902 1903 while (wait(&exit_status) != pid); 1904 1905 if (!WIFEXITED(exit_status)) { 1906 printf("Child exited through unexpected abnormal means\n"); 1907 return false; 1908 } 1909 if (WEXITSTATUS(exit_status) != 42) { 1910 printf("Child exited with wrong exit status\n"); 1911 return false; 1912 } 1913 if (WIFSIGNALED(exit_status)) { 1914 printf("Child recieved unexpected signal\n"); 1915 return false; 1916 } 1917 1918 printf("success: magic_protection\n"); 1919 return true; 1920 } 1366 1921 1367 1922 static void test_reset(void) … … 1380 1935 1381 1936 test_reset(); 1937 ret &= test_pooled_object(); 1938 test_reset(); 1939 ret &= test_pool_nest(); 1940 test_reset(); 1382 1941 ret &= test_ref1(); 1383 1942 test_reset(); … … 1412 1971 ret &= test_free_parent_deny_child(); 1413 1972 test_reset(); 1973 ret &= test_free_parent_reparent_child(); 1974 test_reset(); 1975 ret &= test_free_parent_reparent_child_in_pool(); 1976 test_reset(); 1414 1977 ret &= test_talloc_ptrtype(); 1415 1978 test_reset(); … … 1425 1988 test_reset(); 1426 1989 ret &= test_free_children(); 1990 test_reset(); 1991 ret &= test_memlimit(); 1992 #ifdef HAVE_PTHREAD 1993 test_reset(); 1994 ret &= test_pthread_talloc_passing(); 1995 #endif 1996 1427 1997 1428 1998 if (ret) { … … 1432 2002 test_reset(); 1433 2003 ret &= test_autofree(); 2004 test_reset(); 2005 ret &= test_magic_protection(); 1434 2006 1435 2007 test_reset();
Note:
See TracChangeset
for help on using the changeset viewer.