X-Git-Url: https://git.sven.stormbind.net/?p=sven%2Fexfat-utils.git;a=blobdiff_plain;f=debian%2Fpatches%2Fdetect-infinite-loop;fp=debian%2Fpatches%2Fdetect-infinite-loop;h=94f6bbcf6473a8c61ff705c3346df6a338ca10e7;hp=0000000000000000000000000000000000000000;hb=c26a50397736d869d989d8c3d4dae6e00f28501e;hpb=966875ed51cae814c378c91d3f04e6be53240fd4 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)