OSDN Git Service

Improve upper bound check in CLUSTER_INVALID() macro.
authorrelan <relan@users.noreply.github.com>
Fri, 17 Mar 2017 05:31:43 +0000 (08:31 +0300)
committerrelan <relan@users.noreply.github.com>
Sun, 19 Mar 2017 16:09:17 +0000 (19:09 +0300)
Check that cluster value does not exceed actual number of clusters. Note
that clusters numbering starts with 2.

dump/main.c
fsck/main.c
libexfat/cluster.c
libexfat/exfat.h
libexfat/io.c
libexfat/mount.c
libexfat/node.c

index 420a951..4a764a8 100644 (file)
@@ -168,7 +168,7 @@ static int dump_file_fragments(const char* spec, const char* path)
        {
                off_t lsize;
 
-               if (CLUSTER_INVALID(cluster))
+               if (CLUSTER_INVALID(*ef.sb, cluster))
                {
                        exfat_error("'%s' has invalid cluster %#x", path, cluster);
                        rc = 1;
index b413c58..b7222f0 100644 (file)
@@ -39,7 +39,7 @@ static int nodeck(struct exfat* ef, struct exfat_node* node)
 
        while (clusters--)
        {
-               if (CLUSTER_INVALID(c))
+               if (CLUSTER_INVALID(*ef->sb, c))
                {
                        char name[EXFAT_UTF8_NAME_BUFFER_MAX];
 
index 1d39233..19b7d0d 100644 (file)
@@ -103,7 +103,7 @@ cluster_t exfat_advance_cluster(const struct exfat* ef,
        for (i = node->fptr_index; i < count; i++)
        {
                node->fptr_cluster = exfat_next_cluster(ef, node, node->fptr_cluster);
-               if (CLUSTER_INVALID(node->fptr_cluster))
+               if (CLUSTER_INVALID(*ef->sb, node->fptr_cluster))
                        break; /* the caller should handle this and print appropriate 
                                  error message */
        }
@@ -214,7 +214,7 @@ static cluster_t allocate_cluster(struct exfat* ef, cluster_t hint)
 
 static void free_cluster(struct exfat* ef, cluster_t cluster)
 {
-       if (CLUSTER_INVALID(cluster))
+       if (CLUSTER_INVALID(*ef->sb, cluster))
                exfat_bug("freeing invalid cluster 0x%x", cluster);
        if (cluster - EXFAT_FIRST_DATA_CLUSTER >= ef->cmap.size)
                exfat_bug("freeing non-existing cluster 0x%x (0x%x)", cluster,
@@ -252,7 +252,7 @@ static int grow_file(struct exfat* ef, struct exfat_node* node,
        {
                /* get the last cluster of the file */
                previous = exfat_advance_cluster(ef, node, current - 1);
-               if (CLUSTER_INVALID(previous))
+               if (CLUSTER_INVALID(*ef->sb, previous))
                {
                        exfat_error("invalid cluster 0x%x while growing", previous);
                        return -EIO;
@@ -265,7 +265,7 @@ static int grow_file(struct exfat* ef, struct exfat_node* node,
                /* file does not have clusters (i.e. is empty), allocate
                   the first one for it */
                previous = allocate_cluster(ef, 0);
-               if (CLUSTER_INVALID(previous))
+               if (CLUSTER_INVALID(*ef->sb, previous))
                        return -ENOSPC;
                node->fptr_cluster = node->start_cluster = previous;
                allocated = 1;
@@ -276,7 +276,7 @@ static int grow_file(struct exfat* ef, struct exfat_node* node,
        while (allocated < difference)
        {
                next = allocate_cluster(ef, previous + 1);
-               if (CLUSTER_INVALID(next))
+               if (CLUSTER_INVALID(*ef->sb, next))
                {
                        if (allocated != 0)
                                shrink_file(ef, node, current + allocated, allocated);
@@ -321,7 +321,7 @@ static int shrink_file(struct exfat* ef, struct exfat_node* node,
        {
                cluster_t last = exfat_advance_cluster(ef, node,
                                current - difference - 1);
-               if (CLUSTER_INVALID(last))
+               if (CLUSTER_INVALID(*ef->sb, last))
                {
                        exfat_error("invalid cluster 0x%x while shrinking", last);
                        return -EIO;
@@ -343,12 +343,13 @@ static int shrink_file(struct exfat* ef, struct exfat_node* node,
        /* free remaining clusters */
        while (difference--)
        {
-               if (CLUSTER_INVALID(previous))
+               if (CLUSTER_INVALID(*ef->sb, previous))
                {
                        exfat_error("invalid cluster 0x%x while freeing after shrink",
                                        previous);
                        return -EIO;
                }
+
                next = exfat_next_cluster(ef, node, previous);
                if (!set_next_cluster(ef, node->is_contiguous, previous,
                                EXFAT_CLUSTER_FREE))
@@ -381,7 +382,7 @@ static int erase_range(struct exfat* ef, struct exfat_node* node,
        cluster_boundary = (begin | (CLUSTER_SIZE(*ef->sb) - 1)) + 1;
        cluster = exfat_advance_cluster(ef, node,
                        begin / CLUSTER_SIZE(*ef->sb));
-       if (CLUSTER_INVALID(cluster))
+       if (CLUSTER_INVALID(*ef->sb, cluster))
        {
                exfat_error("invalid cluster 0x%x while erasing", cluster);
                return -EIO;
@@ -395,7 +396,7 @@ static int erase_range(struct exfat* ef, struct exfat_node* node,
        {
                cluster = exfat_next_cluster(ef, node, cluster);
                /* the cluster cannot be invalid because we have just allocated it */
-               if (CLUSTER_INVALID(cluster))
+               if (CLUSTER_INVALID(*ef->sb, cluster))
                        exfat_bug("invalid cluster 0x%x after allocation", cluster);
                if (!erase_raw(ef, CLUSTER_SIZE(*ef->sb), exfat_c2o(ef, cluster)))
                        return -EIO;
index 21b760e..5a60499 100644 (file)
@@ -43,8 +43,8 @@
 
 #define SECTOR_SIZE(sb) (1 << (sb).sector_bits)
 #define CLUSTER_SIZE(sb) (SECTOR_SIZE(sb) << (sb).spc_bits)
-#define CLUSTER_INVALID(c) \
-       ((c) < EXFAT_FIRST_DATA_CLUSTER || (c) > EXFAT_LAST_DATA_CLUSTER)
+#define CLUSTER_INVALID(sb, c) ((c) < EXFAT_FIRST_DATA_CLUSTER || \
+       (c) - EXFAT_FIRST_DATA_CLUSTER >= le32_to_cpu((sb).cluster_count))
 
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
index 514383c..8cbcfa1 100644 (file)
@@ -289,7 +289,7 @@ ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node,
                return 0;
 
        cluster = exfat_advance_cluster(ef, node, offset / CLUSTER_SIZE(*ef->sb));
-       if (CLUSTER_INVALID(cluster))
+       if (CLUSTER_INVALID(*ef->sb, cluster))
        {
                exfat_error("invalid cluster 0x%x while reading", cluster);
                return -EIO;
@@ -299,7 +299,7 @@ ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node,
        remainder = MIN(size, node->size - offset);
        while (remainder > 0)
        {
-               if (CLUSTER_INVALID(cluster))
+               if (CLUSTER_INVALID(*ef->sb, cluster))
                {
                        exfat_error("invalid cluster 0x%x while reading", cluster);
                        return -EIO;
@@ -345,7 +345,7 @@ ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node,
                return 0;
 
        cluster = exfat_advance_cluster(ef, node, offset / CLUSTER_SIZE(*ef->sb));
-       if (CLUSTER_INVALID(cluster))
+       if (CLUSTER_INVALID(*ef->sb, cluster))
        {
                exfat_error("invalid cluster 0x%x while writing", cluster);
                return -EIO;
@@ -355,7 +355,7 @@ ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node,
        remainder = size;
        while (remainder > 0)
        {
-               if (CLUSTER_INVALID(cluster))
+               if (CLUSTER_INVALID(*ef->sb, cluster))
                {
                        exfat_error("invalid cluster 0x%x while writing", cluster);
                        return -EIO;
index f907f29..4910b51 100644 (file)
@@ -44,7 +44,7 @@ static uint64_t rootdir_size(const struct exfat* ef)
                                        clusters);
                        return 0;
                }
-               if (CLUSTER_INVALID(rootdir_cluster))
+               if (CLUSTER_INVALID(*ef->sb, rootdir_cluster))
                {
                        exfat_error("bad cluster %#x while reading root directory",
                                        rootdir_cluster);
index bccf9a1..e50bb69 100644 (file)
@@ -252,7 +252,7 @@ static bool check_node(const struct exfat* ef, struct exfat_node* node,
                                node->start_cluster);
                ret = false;
        }
-       if (node->size > 0 && CLUSTER_INVALID(node->start_cluster))
+       if (node->size > 0 && CLUSTER_INVALID(*ef->sb, node->start_cluster))
        {
                exfat_get_name(node, buffer);
                exfat_error("'%s' points to invalid cluster %#x", buffer,
@@ -401,7 +401,7 @@ static int readdir(struct exfat* ef, struct exfat_node* parent,
                        if (ef->upcase != NULL)
                                break;
                        upcase = (const struct exfat_entry_upcase*) &entry;
-                       if (CLUSTER_INVALID(le32_to_cpu(upcase->start_cluster)))
+                       if (CLUSTER_INVALID(*ef->sb, le32_to_cpu(upcase->start_cluster)))
                        {
                                exfat_error("invalid cluster 0x%x in upcase table",
                                                le32_to_cpu(upcase->start_cluster));
@@ -452,7 +452,7 @@ static int readdir(struct exfat* ef, struct exfat_node* parent,
                case EXFAT_ENTRY_BITMAP:
                        bitmap = (const struct exfat_entry_bitmap*) &entry;
                        ef->cmap.start_cluster = le32_to_cpu(bitmap->start_cluster);
-                       if (CLUSTER_INVALID(ef->cmap.start_cluster))
+                       if (CLUSTER_INVALID(*ef->sb, ef->cmap.start_cluster))
                        {
                                exfat_error("invalid cluster 0x%x in clusters bitmap",
                                                ef->cmap.start_cluster);