test_read_disk_directory_traversals.c (315432) | test_read_disk_directory_traversals.c (348607) |
---|---|
1/*- 2 * Copyright (c) 2010-2012 Michihiro NAKAJIMA 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 26 unchanged lines hidden (view full) --- 35/* 36 * Test if the current filesystem is mounted with noatime option. 37 */ 38static int 39atimeIsUpdated(void) 40{ 41 const char *fn = "fs_noatime"; 42 struct stat st; | 1/*- 2 * Copyright (c) 2010-2012 Michihiro NAKAJIMA 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 26 unchanged lines hidden (view full) --- 35/* 36 * Test if the current filesystem is mounted with noatime option. 37 */ 38static int 39atimeIsUpdated(void) 40{ 41 const char *fn = "fs_noatime"; 42 struct stat st; |
43#if defined(_WIN32) && !defined(CYGWIN) 44 char *buff = NULL; 45 char *ptr; 46 int r; |
|
43 | 47 |
48 r = systemf("fsutil behavior query disableLastAccess > query_atime"); 49 if (r == 0) { 50 buff = slurpfile(NULL, "query_atime"); 51 if (buff != NULL) { 52 ptr = buff; 53 while(*ptr != '\0' && !isdigit(*ptr)) { 54 ptr++; 55 } 56 if (*ptr == '0') { 57 free(buff); 58 return(1); 59 } else if (*ptr == '1' || *ptr == '2') { 60 free(buff); 61 return(0); 62 } 63 free(buff); 64 } 65 } 66#endif |
|
44 if (!assertMakeFile(fn, 0666, "a")) 45 return (0); 46 if (!assertUtimes(fn, 1, 0, 1, 0)) 47 return (0); 48 /* Test the file contents in order to update its atime. */ 49 if (!assertTextFileContents("a", fn)) 50 return (0); 51 if (stat(fn, &st) != 0) --- 513 unchanged lines hidden (view full) --- 565 } 566 567 /* 568 * Create a sample archive. 569 */ 570 assertMakeDir("h", 0755); 571 assertChdir("h"); 572 assertMakeDir("d1", 0755); | 67 if (!assertMakeFile(fn, 0666, "a")) 68 return (0); 69 if (!assertUtimes(fn, 1, 0, 1, 0)) 70 return (0); 71 /* Test the file contents in order to update its atime. */ 72 if (!assertTextFileContents("a", fn)) 73 return (0); 74 if (stat(fn, &st) != 0) --- 513 unchanged lines hidden (view full) --- 588 } 589 590 /* 591 * Create a sample archive. 592 */ 593 assertMakeDir("h", 0755); 594 assertChdir("h"); 595 assertMakeDir("d1", 0755); |
573 assertMakeSymlink("ld1", "d1"); | 596 assertMakeSymlink("ld1", "d1", 1); |
574 assertMakeFile("d1/file1", 0644, "d1/file1"); 575 assertMakeFile("d1/file2", 0644, "d1/file2"); | 597 assertMakeFile("d1/file1", 0644, "d1/file1"); 598 assertMakeFile("d1/file2", 0644, "d1/file2"); |
576 assertMakeSymlink("d1/link1", "file1"); 577 assertMakeSymlink("d1/linkX", "fileX"); 578 assertMakeSymlink("link2", "d1/file2"); 579 assertMakeSymlink("linkY", "d1/fileY"); | 599 assertMakeSymlink("d1/link1", "file1", 0); 600 assertMakeSymlink("d1/linkX", "fileX", 0); 601 assertMakeSymlink("link2", "d1/file2", 0); 602 assertMakeSymlink("linkY", "d1/fileY", 0); |
580 assertChdir(".."); 581 582 assert((ae = archive_entry_new()) != NULL); 583 assert((a = archive_read_disk_new()) != NULL); 584 assertEqualIntA(a, ARCHIVE_OK, 585 archive_read_disk_set_symlink_hybrid(a)); 586 587 /* --- 134 unchanged lines hidden (view full) --- 722 } 723 724 /* 725 * Create a sample archive. 726 */ 727 assertMakeDir("l", 0755); 728 assertChdir("l"); 729 assertMakeDir("d1", 0755); | 603 assertChdir(".."); 604 605 assert((ae = archive_entry_new()) != NULL); 606 assert((a = archive_read_disk_new()) != NULL); 607 assertEqualIntA(a, ARCHIVE_OK, 608 archive_read_disk_set_symlink_hybrid(a)); 609 610 /* --- 134 unchanged lines hidden (view full) --- 745 } 746 747 /* 748 * Create a sample archive. 749 */ 750 assertMakeDir("l", 0755); 751 assertChdir("l"); 752 assertMakeDir("d1", 0755); |
730 assertMakeSymlink("ld1", "d1"); | 753 assertMakeSymlink("ld1", "d1", 1); |
731 assertMakeFile("d1/file1", 0644, "d1/file1"); 732 assertMakeFile("d1/file2", 0644, "d1/file2"); | 754 assertMakeFile("d1/file1", 0644, "d1/file1"); 755 assertMakeFile("d1/file2", 0644, "d1/file2"); |
733 assertMakeSymlink("d1/link1", "file1"); 734 assertMakeSymlink("d1/linkX", "fileX"); 735 assertMakeSymlink("link2", "d1/file2"); 736 assertMakeSymlink("linkY", "d1/fileY"); | 756 assertMakeSymlink("d1/link1", "file1", 0); 757 assertMakeSymlink("d1/linkX", "fileX", 0); 758 assertMakeSymlink("link2", "d1/file2", 0); 759 assertMakeSymlink("linkY", "d1/fileY", 0); |
737 assertChdir(".."); 738 739 /* Note: this test uses archive_read_next_header() 740 instead of archive_read_next_header2() */ 741 assert((a = archive_read_disk_new()) != NULL); 742 assertEqualIntA(a, ARCHIVE_OK, 743 archive_read_disk_set_symlink_logical(a)); 744 --- 211 unchanged lines hidden (view full) --- 956 */ 957 assertMakeDir("l2", 0755); 958 assertChdir("l2"); 959 assertMakeDir("d1", 0755); 960 assertMakeDir("d1/d2", 0755); 961 assertMakeDir("d1/d2/d3", 0755); 962 assertMakeDir("d2", 0755); 963 assertMakeFile("d2/file1", 0644, "d2/file1"); | 760 assertChdir(".."); 761 762 /* Note: this test uses archive_read_next_header() 763 instead of archive_read_next_header2() */ 764 assert((a = archive_read_disk_new()) != NULL); 765 assertEqualIntA(a, ARCHIVE_OK, 766 archive_read_disk_set_symlink_logical(a)); 767 --- 211 unchanged lines hidden (view full) --- 979 */ 980 assertMakeDir("l2", 0755); 981 assertChdir("l2"); 982 assertMakeDir("d1", 0755); 983 assertMakeDir("d1/d2", 0755); 984 assertMakeDir("d1/d2/d3", 0755); 985 assertMakeDir("d2", 0755); 986 assertMakeFile("d2/file1", 0644, "d2/file1"); |
964 assertMakeSymlink("d1/d2/ld1", "../../d1"); 965 assertMakeSymlink("d1/d2/ld2", "../../d2"); | 987 assertMakeSymlink("d1/d2/ld1", "../../d1", 1); 988 assertMakeSymlink("d1/d2/ld2", "../../d2", 1); |
966 assertChdir(".."); 967 968 assert((ae = archive_entry_new()) != NULL); 969 assert((a = archive_read_disk_new()) != NULL); 970 assertEqualIntA(a, ARCHIVE_OK, 971 archive_read_disk_set_symlink_logical(a)); 972 973 /* --- 588 unchanged lines hidden (view full) --- 1562 failure("Atime should be restored"); 1563 assertFileAtime("nd/f2", 886611, 0); 1564 1565 /* Destroy the disk object. */ 1566 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1567 archive_entry_free(ae); 1568} 1569 | 989 assertChdir(".."); 990 991 assert((ae = archive_entry_new()) != NULL); 992 assert((a = archive_read_disk_new()) != NULL); 993 assertEqualIntA(a, ARCHIVE_OK, 994 archive_read_disk_set_symlink_logical(a)); 995 996 /* --- 588 unchanged lines hidden (view full) --- 1585 failure("Atime should be restored"); 1586 assertFileAtime("nd/f2", 886611, 0); 1587 1588 /* Destroy the disk object. */ 1589 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1590 archive_entry_free(ae); 1591} 1592 |
1593static void 1594test_parent(void) 1595{ 1596 struct archive *a; 1597 struct archive_entry *ae; 1598 const void *p; 1599 size_t size; 1600 int64_t offset; 1601 int file_count; 1602 int match_count; 1603 int r; 1604 1605 assertMakeDir("lock", 0311); 1606 assertMakeDir("lock/dir1", 0755); 1607 assertMakeFile("lock/dir1/f1", 0644, "0123456789"); 1608 assertMakeDir("lock/lock2", 0311); 1609 assertMakeDir("lock/lock2/dir1", 0755); 1610 assertMakeFile("lock/lock2/dir1/f1", 0644, "0123456789"); 1611 1612 assert((ae = archive_entry_new()) != NULL); 1613 assert((a = archive_read_disk_new()) != NULL); 1614 1615 /* 1616 * Test1: Traverse lock/dir1 as . 1617 */ 1618 assertChdir("lock/dir1"); 1619 1620 failure("Directory traversals should work as well"); 1621 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, ".")); 1622 1623 file_count = 2; 1624 match_count = 0; 1625 while (file_count--) { 1626 archive_entry_clear(ae); 1627 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1628 if (strcmp(archive_entry_pathname(ae), ".") == 0) { 1629 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1630 ++match_count; 1631 } else if (strcmp(archive_entry_pathname(ae), "./f1") == 0) { 1632 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1633 assertEqualInt(archive_entry_size(ae), 10); 1634 assertEqualIntA(a, ARCHIVE_OK, 1635 archive_read_data_block(a, &p, &size, &offset)); 1636 assertEqualInt((int)size, 10); 1637 assertEqualInt((int)offset, 0); 1638 assertEqualMem(p, "0123456789", 10); 1639 assertEqualInt(ARCHIVE_EOF, 1640 archive_read_data_block(a, &p, &size, &offset)); 1641 assertEqualInt((int)size, 0); 1642 assertEqualInt((int)offset, 10); 1643 ++match_count; 1644 } 1645 if (archive_read_disk_can_descend(a)) { 1646 /* Descend into the current object */ 1647 assertEqualIntA(a, ARCHIVE_OK, 1648 archive_read_disk_descend(a)); 1649 } 1650 } 1651 failure("Did not match expected filenames"); 1652 assertEqualInt(match_count, 2); 1653 /* 1654 * There is no entry. This will however fail if the directory traverse 1655 * tries to ascend past the initial directory, since it lacks permission 1656 * to do so. 1657 */ 1658 failure("There should be no entry and no error"); 1659 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1660 1661 /* Close the disk object. */ 1662 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1663 1664 assertChdir("../.."); 1665 1666 /* 1667 * Test2: Traverse lock/dir1 directly 1668 */ 1669 failure("Directory traversals should work as well"); 1670 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock/dir1")); 1671 1672 file_count = 2; 1673 match_count = 0; 1674 while (file_count--) { 1675 archive_entry_clear(ae); 1676 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1677 if (strcmp(archive_entry_pathname(ae), "lock/dir1") == 0) { 1678 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1679 ++match_count; 1680 } else if (strcmp(archive_entry_pathname(ae), "lock/dir1/f1") == 0) { 1681 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1682 assertEqualInt(archive_entry_size(ae), 10); 1683 assertEqualIntA(a, ARCHIVE_OK, 1684 archive_read_data_block(a, &p, &size, &offset)); 1685 assertEqualInt((int)size, 10); 1686 assertEqualInt((int)offset, 0); 1687 assertEqualMem(p, "0123456789", 10); 1688 assertEqualInt(ARCHIVE_EOF, 1689 archive_read_data_block(a, &p, &size, &offset)); 1690 assertEqualInt((int)size, 0); 1691 assertEqualInt((int)offset, 10); 1692 ++match_count; 1693 } 1694 if (archive_read_disk_can_descend(a)) { 1695 /* Descend into the current object */ 1696 assertEqualIntA(a, ARCHIVE_OK, 1697 archive_read_disk_descend(a)); 1698 } 1699 } 1700 failure("Did not match expected filenames"); 1701 assertEqualInt(match_count, 2); 1702 /* 1703 * There is no entry. This will however fail if the directory traverse 1704 * tries to ascend past the initial directory, since it lacks permission 1705 * to do so. 1706 */ 1707 failure("There should be no entry and no error"); 1708 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1709 1710 /* Close the disk object. */ 1711 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1712 1713 /* 1714 * Test3: Traverse lock/dir1/. 1715 */ 1716 failure("Directory traversals should work as well"); 1717 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock/dir1/.")); 1718 1719 file_count = 2; 1720 match_count = 0; 1721 while (file_count--) { 1722 archive_entry_clear(ae); 1723 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1724 if (strcmp(archive_entry_pathname(ae), "lock/dir1/.") == 0) { 1725 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1726 ++match_count; 1727 } else if (strcmp(archive_entry_pathname(ae), "lock/dir1/./f1") == 0) { 1728 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1729 assertEqualInt(archive_entry_size(ae), 10); 1730 assertEqualIntA(a, ARCHIVE_OK, 1731 archive_read_data_block(a, &p, &size, &offset)); 1732 assertEqualInt((int)size, 10); 1733 assertEqualInt((int)offset, 0); 1734 assertEqualMem(p, "0123456789", 10); 1735 assertEqualInt(ARCHIVE_EOF, 1736 archive_read_data_block(a, &p, &size, &offset)); 1737 assertEqualInt((int)size, 0); 1738 assertEqualInt((int)offset, 10); 1739 ++match_count; 1740 } 1741 if (archive_read_disk_can_descend(a)) { 1742 /* Descend into the current object */ 1743 assertEqualIntA(a, ARCHIVE_OK, 1744 archive_read_disk_descend(a)); 1745 } 1746 } 1747 failure("Did not match expected filenames"); 1748 assertEqualInt(match_count, 2); 1749 /* 1750 * There is no entry. This will however fail if the directory traverse 1751 * tries to ascend past the initial directory, since it lacks permission 1752 * to do so. 1753 */ 1754 failure("There should be no entry and no error"); 1755 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1756 1757 /* Close the disk object. */ 1758 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1759 1760 /* 1761 * Test4: Traverse lock/lock2/dir1 from inside lock. 1762 * 1763 * This test is expected to fail on platforms with no O_EXEC or 1764 * equivalent (e.g. O_PATH on Linux or O_SEARCH on SunOS), because 1765 * the current traversal code can't handle the case where it can't 1766 * obtain an open fd for the initial current directory. We need to 1767 * check that condition here, because if O_EXEC _does_ exist, we don't 1768 * want to overlook any failure. 1769 */ 1770 assertChdir("lock"); 1771 1772 failure("Directory traversals should work as well"); 1773 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock2/dir1")); 1774 1775 archive_entry_clear(ae); 1776 r = archive_read_next_header2(a, ae); 1777 if (r == ARCHIVE_FAILED) { 1778#if defined(O_PATH) || defined(O_SEARCH) || defined(O_EXEC) 1779 assertEqualIntA(a, ARCHIVE_OK, r); 1780#endif 1781 /* Close the disk object. */ 1782 archive_read_close(a); 1783 } else { 1784 file_count = 2; 1785 match_count = 0; 1786 while (file_count--) { 1787 if (file_count == 0) 1788 assertEqualIntA(a, ARCHIVE_OK, 1789 archive_read_next_header2(a, ae)); 1790 if (strcmp(archive_entry_pathname(ae), 1791 "lock2/dir1") == 0) { 1792 assertEqualInt(archive_entry_filetype(ae), 1793 AE_IFDIR); 1794 ++match_count; 1795 } else if (strcmp(archive_entry_pathname(ae), 1796 "lock2/dir1/f1") == 0) { 1797 assertEqualInt(archive_entry_filetype(ae), 1798 AE_IFREG); 1799 assertEqualInt(archive_entry_size(ae), 10); 1800 assertEqualIntA(a, ARCHIVE_OK, 1801 archive_read_data_block(a, &p, &size, 1802 &offset)); 1803 assertEqualInt((int)size, 10); 1804 assertEqualInt((int)offset, 0); 1805 assertEqualMem(p, "0123456789", 10); 1806 assertEqualInt(ARCHIVE_EOF, 1807 archive_read_data_block(a, &p, &size, 1808 &offset)); 1809 assertEqualInt((int)size, 0); 1810 assertEqualInt((int)offset, 10); 1811 ++match_count; 1812 } 1813 if (archive_read_disk_can_descend(a)) { 1814 /* Descend into the current object */ 1815 assertEqualIntA(a, ARCHIVE_OK, 1816 archive_read_disk_descend(a)); 1817 } 1818 } 1819 failure("Did not match expected filenames"); 1820 assertEqualInt(match_count, 2); 1821 /* 1822 * There is no entry. This will however fail if the directory 1823 * traverse tries to ascend past the initial directory, since 1824 * it lacks permission to do so. 1825 */ 1826 failure("There should be no entry and no error"); 1827 assertEqualIntA(a, ARCHIVE_EOF, 1828 archive_read_next_header2(a, ae)); 1829 1830 /* Close the disk object. */ 1831 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1832 } 1833 1834 assertChdir(".."); 1835 1836 /* Destroy the disk object. */ 1837 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1838 archive_entry_free(ae); 1839} 1840 |
|
1570DEFINE_TEST(test_read_disk_directory_traversals) 1571{ 1572 /* Basic test. */ 1573 test_basic(); 1574 /* Test hybrid mode; follow symlink initially, then not. */ 1575 test_symlink_hybrid(); 1576 /* Test logical mode; follow all symlinks. */ 1577 test_symlink_logical(); 1578 /* Test logical mode; prevent loop in symlinks. */ 1579 test_symlink_logical_loop(); 1580 /* Test to restore atime. */ 1581 test_restore_atime(); 1582 /* Test callbacks. */ 1583 test_callbacks(); 1584 /* Test nodump. */ 1585 test_nodump(); | 1841DEFINE_TEST(test_read_disk_directory_traversals) 1842{ 1843 /* Basic test. */ 1844 test_basic(); 1845 /* Test hybrid mode; follow symlink initially, then not. */ 1846 test_symlink_hybrid(); 1847 /* Test logical mode; follow all symlinks. */ 1848 test_symlink_logical(); 1849 /* Test logical mode; prevent loop in symlinks. */ 1850 test_symlink_logical_loop(); 1851 /* Test to restore atime. */ 1852 test_restore_atime(); 1853 /* Test callbacks. */ 1854 test_callbacks(); 1855 /* Test nodump. */ 1856 test_nodump(); |
1857 /* Test parent overshoot. */ 1858 test_parent(); |
|
1586} | 1859} |