OSDN Git Service

fs/adfs: bigdir: extract directory validation
authorRussell King <rmk+kernel@armlinux.org.uk>
Mon, 9 Dec 2019 11:10:57 +0000 (11:10 +0000)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 21 Jan 2020 01:12:42 +0000 (20:12 -0500)
Extract the directory validation from the directory reading function as
we will want to re-use this code.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/adfs/dir_fplus.c

index 393921f..b83a74e 100644 (file)
@@ -16,6 +16,30 @@ static unsigned int adfs_fplus_offset(const struct adfs_bigdirheader *h,
               pos * sizeof(struct adfs_bigdirentry);
 }
 
+static int adfs_fplus_validate_header(const struct adfs_bigdirheader *h)
+{
+       unsigned int size = le32_to_cpu(h->bigdirsize);
+
+       if (h->bigdirversion[0] != 0 || h->bigdirversion[1] != 0 ||
+           h->bigdirversion[2] != 0 ||
+           h->bigdirstartname != cpu_to_le32(BIGDIRSTARTNAME) ||
+           size & 2047)
+               return -EIO;
+
+       return 0;
+}
+
+static int adfs_fplus_validate_tail(const struct adfs_bigdirheader *h,
+                                   const struct adfs_bigdirtail *t)
+{
+       if (t->bigdirendname != cpu_to_le32(BIGDIRENDNAME) ||
+           t->bigdirendmasseq != h->startmasseq ||
+           t->reserved[0] != 0 || t->reserved[1] != 0)
+               return -EIO;
+
+       return 0;
+}
+
 static int adfs_fplus_read(struct super_block *sb, u32 indaddr,
                           unsigned int size, struct adfs_dir *dir)
 {
@@ -30,6 +54,11 @@ static int adfs_fplus_read(struct super_block *sb, u32 indaddr,
                return ret;
 
        dir->bighead = h = (void *)dir->bhs[0]->b_data;
+       if (adfs_fplus_validate_header(h)) {
+               adfs_error(sb, "dir %06x has malformed header", indaddr);
+               goto out;
+       }
+
        dirsize = le32_to_cpu(h->bigdirsize);
        if (dirsize != size) {
                adfs_msg(sb, KERN_WARNING,
@@ -37,13 +66,6 @@ static int adfs_fplus_read(struct super_block *sb, u32 indaddr,
                         indaddr, dirsize, size);
        }
 
-       if (h->bigdirversion[0] != 0 || h->bigdirversion[1] != 0 ||
-           h->bigdirversion[2] != 0 || size & 2047 ||
-           h->bigdirstartname != cpu_to_le32(BIGDIRSTARTNAME)) {
-               adfs_error(sb, "dir %06x has malformed header", indaddr);
-               goto out;
-       }
-
        /* Read remaining buffers */
        ret = adfs_dir_read_buffers(sb, indaddr, dirsize, dir);
        if (ret)
@@ -52,9 +74,8 @@ static int adfs_fplus_read(struct super_block *sb, u32 indaddr,
        dir->bigtail = t = (struct adfs_bigdirtail *)
                (dir->bhs[dir->nr_buffers - 1]->b_data + (sb->s_blocksize - 8));
 
-       if (t->bigdirendname != cpu_to_le32(BIGDIRENDNAME) ||
-           t->bigdirendmasseq != h->startmasseq ||
-           t->reserved[0] != 0 || t->reserved[1] != 0) {
+       ret = adfs_fplus_validate_tail(h, t);
+       if (ret) {
                adfs_error(sb, "dir %06x has malformed tail", indaddr);
                goto out;
        }