Sat Jun 10 12:46:32 2023 UTC ()
libarchive: fail if name_max is 0

Add error handling to the USE_READDIR_R code paths that set name_max
from struct statfs or statvfs; if the determined name_max == 0
then return an error.

Avoids a crash in tree_dir_next_posix() when the calculation of
dirent_size from name_max is too small for the memory allocated
for struct dirent.

Submitted to upstream in pull request
	https://github.com/libarchive/libarchive/pull/1903

Should fix PR bin/56080


(lukem)
diff -r1.2 -r1.3 src/external/bsd/libarchive/dist/libarchive/archive_read_disk_posix.c

cvs diff -r1.2 -r1.3 src/external/bsd/libarchive/dist/libarchive/archive_read_disk_posix.c (expand / switch to unified diff)

--- src/external/bsd/libarchive/dist/libarchive/archive_read_disk_posix.c 2021/03/29 15:31:46 1.2
+++ src/external/bsd/libarchive/dist/libarchive/archive_read_disk_posix.c 2023/06/10 12:46:32 1.3
@@ -1643,26 +1643,31 @@ setup_current_filesystem(struct archive_ @@ -1643,26 +1643,31 @@ setup_current_filesystem(struct archive_
1643 return (ARCHIVE_FAILED); 1643 return (ARCHIVE_FAILED);
1644 } 1644 }
1645 nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX); 1645 nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
1646 } else 1646 } else
1647 nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX); 1647 nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
1648# else 1648# else
1649 nm = -1; 1649 nm = -1;
1650# endif 1650# endif
1651 if (nm == -1) 1651 if (nm == -1)
1652 t->current_filesystem->name_max = NAME_MAX; 1652 t->current_filesystem->name_max = NAME_MAX;
1653 else 1653 else
1654 t->current_filesystem->name_max = nm; 1654 t->current_filesystem->name_max = nm;
1655#endif 1655#endif
 1656 if (t->current_filesystem->name_max == 0) {
 1657 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 1658 "Cannot determine name_max");
 1659 return (ARCHIVE_FAILED);
 1660 }
1656#endif /* USE_READDIR_R */ 1661#endif /* USE_READDIR_R */
1657 return (ARCHIVE_OK); 1662 return (ARCHIVE_OK);
1658} 1663}
1659 1664
1660#elif (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS)) && defined(ST_LOCAL) 1665#elif (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS)) && defined(ST_LOCAL)
1661 1666
1662static void 1667static void
1663set_transfer_size(struct filesystem *fs, const struct statvfs *sfs) 1668set_transfer_size(struct filesystem *fs, const struct statvfs *sfs)
1664{ 1669{
1665 fs->xfer_align = sfs->f_frsize > 0 ? (long)sfs->f_frsize : -1; 1670 fs->xfer_align = sfs->f_frsize > 0 ? (long)sfs->f_frsize : -1;
1666 fs->max_xfer_size = -1; 1671 fs->max_xfer_size = -1;
1667#if defined(HAVE_STRUCT_STATVFS_F_IOSIZE) 1672#if defined(HAVE_STRUCT_STATVFS_F_IOSIZE)
1668 fs->min_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1; 1673 fs->min_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1;
@@ -1716,26 +1721,31 @@ setup_current_filesystem(struct archive_ @@ -1716,26 +1721,31 @@ setup_current_filesystem(struct archive_
1716 t->current_filesystem->remote = 0; 1721 t->current_filesystem->remote = 0;
1717 else 1722 else
1718 t->current_filesystem->remote = 1; 1723 t->current_filesystem->remote = 1;
1719 1724
1720#if defined(ST_NOATIME) 1725#if defined(ST_NOATIME)
1721 if (sfs.f_flag & ST_NOATIME) 1726 if (sfs.f_flag & ST_NOATIME)
1722 t->current_filesystem->noatime = 1; 1727 t->current_filesystem->noatime = 1;
1723 else 1728 else
1724#endif 1729#endif
1725 t->current_filesystem->noatime = 0; 1730 t->current_filesystem->noatime = 0;
1726 1731
1727 /* Set maximum filename length. */ 1732 /* Set maximum filename length. */
1728 t->current_filesystem->name_max = sfs.f_namemax; 1733 t->current_filesystem->name_max = sfs.f_namemax;
 1734 if (t->current_filesystem->name_max == 0) {
 1735 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 1736 "Cannot determine name_max");
 1737 return (ARCHIVE_FAILED);
 1738 }
1729 return (ARCHIVE_OK); 1739 return (ARCHIVE_OK);
1730} 1740}
1731 1741
1732#elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_LINUX_MAGIC_H) &&\ 1742#elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_LINUX_MAGIC_H) &&\
1733 defined(HAVE_STATFS) && defined(HAVE_FSTATFS) 1743 defined(HAVE_STATFS) && defined(HAVE_FSTATFS)
1734/* 1744/*
1735 * Note: statfs is deprecated since LSB 3.2 1745 * Note: statfs is deprecated since LSB 3.2
1736 */ 1746 */
1737 1747
1738#ifndef CIFS_SUPER_MAGIC 1748#ifndef CIFS_SUPER_MAGIC
1739#define CIFS_SUPER_MAGIC 0xFF534D42 1749#define CIFS_SUPER_MAGIC 0xFF534D42
1740#endif 1750#endif
1741#ifndef DEVFS_SUPER_MAGIC 1751#ifndef DEVFS_SUPER_MAGIC
@@ -1848,26 +1858,31 @@ setup_current_filesystem(struct archive_ @@ -1848,26 +1858,31 @@ setup_current_filesystem(struct archive_
1848#if defined(HAVE_STATVFS) 1858#if defined(HAVE_STATVFS)
1849 if (svfs.f_flag & ST_NOATIME) 1859 if (svfs.f_flag & ST_NOATIME)
1850#else 1860#else
1851 if (sfs.f_flag & ST_NOATIME) 1861 if (sfs.f_flag & ST_NOATIME)
1852#endif 1862#endif
1853 t->current_filesystem->noatime = 1; 1863 t->current_filesystem->noatime = 1;
1854 else 1864 else
1855#endif 1865#endif
1856 t->current_filesystem->noatime = 0; 1866 t->current_filesystem->noatime = 0;
1857 1867
1858#if defined(USE_READDIR_R) 1868#if defined(USE_READDIR_R)
1859 /* Set maximum filename length. */ 1869 /* Set maximum filename length. */
1860 t->current_filesystem->name_max = sfs.f_namelen; 1870 t->current_filesystem->name_max = sfs.f_namelen;
 1871 if (t->current_filesystem->name_max == 0) {
 1872 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 1873 "Cannot determine name_max");
 1874 return (ARCHIVE_FAILED);
 1875 }
1861#endif 1876#endif
1862 return (ARCHIVE_OK); 1877 return (ARCHIVE_OK);
1863} 1878}
1864 1879
1865#elif defined(HAVE_SYS_STATVFS_H) &&\ 1880#elif defined(HAVE_SYS_STATVFS_H) &&\
1866 (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS)) 1881 (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS))
1867 1882
1868/* 1883/*
1869 * Gather current filesystem properties on other posix platform. 1884 * Gather current filesystem properties on other posix platform.
1870 */ 1885 */
1871static int 1886static int
1872setup_current_filesystem(struct archive_read_disk *a) 1887setup_current_filesystem(struct archive_read_disk *a)
1873{ 1888{
@@ -1929,26 +1944,31 @@ setup_current_filesystem(struct archive_ @@ -1929,26 +1944,31 @@ setup_current_filesystem(struct archive_
1929 set_transfer_size(t->current_filesystem, &sfs); 1944 set_transfer_size(t->current_filesystem, &sfs);
1930 } 1945 }
1931 1946
1932#if defined(ST_NOATIME) 1947#if defined(ST_NOATIME)
1933 if (sfs.f_flag & ST_NOATIME) 1948 if (sfs.f_flag & ST_NOATIME)
1934 t->current_filesystem->noatime = 1; 1949 t->current_filesystem->noatime = 1;
1935 else 1950 else
1936#endif 1951#endif
1937 t->current_filesystem->noatime = 0; 1952 t->current_filesystem->noatime = 0;
1938 1953
1939#if defined(USE_READDIR_R) 1954#if defined(USE_READDIR_R)
1940 /* Set maximum filename length. */ 1955 /* Set maximum filename length. */
1941 t->current_filesystem->name_max = sfs.f_namemax; 1956 t->current_filesystem->name_max = sfs.f_namemax;
 1957 if (t->current_filesystem->name_max == 0) {
 1958 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 1959 "Cannot determine name_max");
 1960 return (ARCHIVE_FAILED);
 1961 }
1942#endif 1962#endif
1943 return (ARCHIVE_OK); 1963 return (ARCHIVE_OK);
1944} 1964}
1945 1965
1946#else 1966#else
1947 1967
1948/* 1968/*
1949 * Generic: Gather current filesystem properties. 1969 * Generic: Gather current filesystem properties.
1950 * TODO: Is this generic function really needed? 1970 * TODO: Is this generic function really needed?
1951 */ 1971 */
1952static int 1972static int
1953setup_current_filesystem(struct archive_read_disk *a) 1973setup_current_filesystem(struct archive_read_disk *a)
1954{ 1974{
@@ -1983,26 +2003,31 @@ setup_current_filesystem(struct archive_ @@ -1983,26 +2003,31 @@ setup_current_filesystem(struct archive_
1983 * NAME_MAX macro to be a smaller value. 2003 * NAME_MAX macro to be a smaller value.
1984 */ 2004 */
1985# if defined(NAME_MAX) && NAME_MAX >= 255 2005# if defined(NAME_MAX) && NAME_MAX >= 255
1986 t->current_filesystem->name_max = NAME_MAX; 2006 t->current_filesystem->name_max = NAME_MAX;
1987# else 2007# else
1988 /* No way to get a trusted value of maximum filename 2008 /* No way to get a trusted value of maximum filename
1989 * length. */ 2009 * length. */
1990 t->current_filesystem->name_max = PATH_MAX; 2010 t->current_filesystem->name_max = PATH_MAX;
1991# endif /* NAME_MAX */ 2011# endif /* NAME_MAX */
1992# if defined(_PC_NAME_MAX) 2012# if defined(_PC_NAME_MAX)
1993 else 2013 else
1994 t->current_filesystem->name_max = nm; 2014 t->current_filesystem->name_max = nm;
1995# endif /* _PC_NAME_MAX */ 2015# endif /* _PC_NAME_MAX */
 2016 if (t->current_filesystem->name_max == 0) {
 2017 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 2018 "Cannot determine name_max");
 2019 return (ARCHIVE_FAILED);
 2020 }
1996#endif /* USE_READDIR_R */ 2021#endif /* USE_READDIR_R */
1997 return (ARCHIVE_OK); 2022 return (ARCHIVE_OK);
1998} 2023}
1999 2024
2000#endif 2025#endif
2001 2026
2002static int 2027static int
2003close_and_restore_time(int fd, struct tree *t, struct restore_time *rt) 2028close_and_restore_time(int fd, struct tree *t, struct restore_time *rt)
2004{ 2029{
2005#ifndef HAVE_UTIMES 2030#ifndef HAVE_UTIMES
2006 (void)t; /* UNUSED */ 2031 (void)t; /* UNUSED */
2007 (void)rt; /* UNUSED */ 2032 (void)rt; /* UNUSED */
2008 return (close(fd)); 2033 return (close(fd));