From c26a50397736d869d989d8c3d4dae6e00f28501e Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Thu, 29 Oct 2015 12:38:42 +0100 Subject: [PATCH] Add d/patches/check-sector-and-cluster-size. Fix for https://github.com/relan/exfat/issues/5 found and reported by The Fuzzing Project. Add d/patches/detect-infinite-loop. Fix for https://github.com/relan/exfat/issues/6 found and reported by The Fuzzing Project. --- debian/changelog | 11 +++++ debian/patches/check-sector-and-cluster-size | 49 ++++++++++++++++++++ debian/patches/detect-infinite-loop | 48 +++++++++++++++++++ debian/patches/series | 2 + 4 files changed, 110 insertions(+) create mode 100644 debian/patches/check-sector-and-cluster-size create mode 100644 debian/patches/detect-infinite-loop diff --git a/debian/changelog b/debian/changelog index b94d07d..51af2ac 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,14 @@ +exfat-utils (0.9.7-2+deb7u1) UNRELEASED; urgency=medium + + * Add d/patches/check-sector-and-cluster-size. Fix for + https://github.com/relan/exfat/issues/5 found and reported by + The Fuzzing Project. + * Add d/patches/detect-infinite-loop. Fix for + https://github.com/relan/exfat/issues/6 found and reported by + The Fuzzing Project. + + -- Sven Hoexter Thu, 29 Oct 2015 12:37:48 +0100 + exfat-utils (0.9.7-2) unstable; urgency=low * Move manual link creation from debian/rules to debian/links diff --git a/debian/patches/check-sector-and-cluster-size b/debian/patches/check-sector-and-cluster-size new file mode 100644 index 0000000..c630c2d --- /dev/null +++ b/debian/patches/check-sector-and-cluster-size @@ -0,0 +1,49 @@ +Patch for https://github.com/relan/exfat/issues/5 +See also: +https://blog.fuzzing-project.org/25-Heap-overflow-and-endless-loop-in-exfatfsck-exfat-utils.html +Index: exfat-utils/libexfat/mount.c +=================================================================== +--- exfat-utils.orig/libexfat/mount.c ++++ exfat-utils/libexfat/mount.c +@@ -172,6 +172,24 @@ int exfat_mount(struct exfat* ef, const + exfat_error("exFAT file system is not found"); + return -EIO; + } ++ /* sector cannot be smaller than 512 bytes */ ++ if (ef->sb->sector_bits < 9) ++ { ++ exfat_close(ef->dev); ++ exfat_error("too small sector size: 2^%hhd", ef->sb->sector_bits); ++ free(ef->sb); ++ return -EIO; ++ } ++ /* officially exFAT supports cluster size up to 32 MB */ ++ if ((int) ef->sb->sector_bits + (int) ef->sb->spc_bits > 25) ++ { ++ exfat_close(ef->dev); ++ exfat_error("too big cluster size: 2^(%hhd+%hhd)", ++ ef->sb->sector_bits, ef->sb->spc_bits); ++ free(ef->sb); ++ return -EIO; ++ } ++ + if (ef->sb->version.major != 1 || ef->sb->version.minor != 0) + { + exfat_close(ef->dev); +@@ -187,16 +205,6 @@ int exfat_mount(struct exfat* ef, const + exfat_error("unsupported FAT count: %hhu", ef->sb->fat_count); + return -EIO; + } +- /* officially exFAT supports cluster size up to 32 MB */ +- if ((int) ef->sb->sector_bits + (int) ef->sb->spc_bits > 25) +- { +- exfat_close(ef->dev); +- free(ef->sb); +- exfat_error("too big cluster size: 2^%d", +- (int) ef->sb->sector_bits + (int) ef->sb->spc_bits); +- return -EIO; +- } +- + ef->zero_cluster = malloc(CLUSTER_SIZE(*ef->sb)); + if (ef->zero_cluster == NULL) + { diff --git a/debian/patches/detect-infinite-loop b/debian/patches/detect-infinite-loop new file mode 100644 index 0000000..94f6bbc --- /dev/null +++ b/debian/patches/detect-infinite-loop @@ -0,0 +1,48 @@ +Patch for https://github.com/relan/exfat/issues/6 +See also: +https://blog.fuzzing-project.org/25-Heap-overflow-and-endless-loop-in-exfatfsck-exfat-utils.html +Index: exfat-utils/libexfat/mount.c +=================================================================== +--- exfat-utils.orig/libexfat/mount.c ++++ exfat-utils/libexfat/mount.c +@@ -27,17 +27,32 @@ + + static uint64_t rootdir_size(const struct exfat* ef) + { +- uint64_t clusters = 0; ++ uint32_t clusters = 0; ++ uint32_t clusters_max = le32_to_cpu(ef->sb->cluster_count); + cluster_t rootdir_cluster = le32_to_cpu(ef->sb->rootdir_cluster); + +- while (!CLUSTER_INVALID(rootdir_cluster)) +- { +- clusters++; +- /* root directory cannot be contiguous because there is no flag +- to indicate this */ +- rootdir_cluster = exfat_next_cluster(ef, ef->root, rootdir_cluster); ++ /* Iterate all clusters of the root directory to calculate its size. ++ It can't be contiguous because there is no flag to indicate this. */ ++ do ++ { ++ if (clusters == clusters_max) /* infinite loop detected */ ++ { ++ exfat_error("root directory cannot occupy all %d clusters", ++ clusters); ++ return 0; ++ } ++ if (CLUSTER_INVALID(rootdir_cluster)) ++ { ++ exfat_error("bad cluster %#x while reading root directory", ++ rootdir_cluster); ++ return 0; ++ } ++ rootdir_cluster = exfat_next_cluster(ef, ef->root, rootdir_cluster); ++ clusters++; + } +- return clusters * CLUSTER_SIZE(*ef->sb); ++ while (rootdir_cluster != EXFAT_CLUSTER_END); ++ ++ return (uint64_t) clusters * CLUSTER_SIZE(*ef->sb); + } + + static const char* get_option(const char* options, const char* option_name) diff --git a/debian/patches/series b/debian/patches/series index e3ec1be..de54dee 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,2 +1,4 @@ honor-cppflags utf16-fix +check-sector-and-cluster-size +detect-infinite-loop -- 2.39.2