Merge tag 'ntfs3_for_6.2' of https://github.com/Paragon-Software-Group/linux-ntfs3
[platform/kernel/linux-rpi.git] / fs / ntfs3 / fslog.c
index 0d611a6..c6eb371 100644 (file)
@@ -1132,7 +1132,7 @@ static int read_log_page(struct ntfs_log *log, u32 vbo,
                return -EINVAL;
 
        if (!*buffer) {
-               to_free = kmalloc(bytes, GFP_NOFS);
+               to_free = kmalloc(log->page_size, GFP_NOFS);
                if (!to_free)
                        return -ENOMEM;
                *buffer = to_free;
@@ -1180,10 +1180,7 @@ static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
                        struct restart_info *info)
 {
        u32 skip, vbo;
-       struct RESTART_HDR *r_page = kmalloc(DefaultLogPageSize, GFP_NOFS);
-
-       if (!r_page)
-               return -ENOMEM;
+       struct RESTART_HDR *r_page = NULL;
 
        /* Determine which restart area we are looking for. */
        if (first) {
@@ -1197,7 +1194,6 @@ static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
        /* Loop continuously until we succeed. */
        for (; vbo < l_size; vbo = 2 * vbo + skip, skip = 0) {
                bool usa_error;
-               u32 sys_page_size;
                bool brst, bchk;
                struct RESTART_AREA *ra;
 
@@ -1251,24 +1247,6 @@ static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
                        goto check_result;
                }
 
-               /* Read the entire restart area. */
-               sys_page_size = le32_to_cpu(r_page->sys_page_size);
-               if (DefaultLogPageSize != sys_page_size) {
-                       kfree(r_page);
-                       r_page = kzalloc(sys_page_size, GFP_NOFS);
-                       if (!r_page)
-                               return -ENOMEM;
-
-                       if (read_log_page(log, vbo,
-                                         (struct RECORD_PAGE_HDR **)&r_page,
-                                         &usa_error)) {
-                               /* Ignore any errors. */
-                               kfree(r_page);
-                               r_page = NULL;
-                               continue;
-                       }
-               }
-
                if (is_client_area_valid(r_page, usa_error)) {
                        info->valid_page = true;
                        ra = Add2Ptr(r_page, le16_to_cpu(r_page->ra_off));
@@ -2727,6 +2705,9 @@ static inline bool check_attr(const struct MFT_REC *rec,
                        return false;
                }
 
+               if (run_off > asize)
+                       return false;
+
                if (run_unpack(NULL, sbi, 0, svcn, evcn, svcn,
                               Add2Ptr(attr, run_off), asize - run_off) < 0) {
                        return false;
@@ -3048,7 +3029,7 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe,
        struct NEW_ATTRIBUTE_SIZES *new_sz;
        struct ATTR_FILE_NAME *fname;
        struct OpenAttr *oa, *oa2;
-       u32 nsize, t32, asize, used, esize, bmp_off, bmp_bits;
+       u32 nsize, t32, asize, used, esize, off, bits;
        u16 id, id2;
        u32 record_size = sbi->record_size;
        u64 t64;
@@ -3635,30 +3616,28 @@ move_data:
                break;
 
        case SetBitsInNonresidentBitMap:
-               bmp_off =
-                       le32_to_cpu(((struct BITMAP_RANGE *)data)->bitmap_off);
-               bmp_bits = le32_to_cpu(((struct BITMAP_RANGE *)data)->bits);
+               off = le32_to_cpu(((struct BITMAP_RANGE *)data)->bitmap_off);
+               bits = le32_to_cpu(((struct BITMAP_RANGE *)data)->bits);
 
-               if (cbo + (bmp_off + 7) / 8 > lco ||
-                   cbo + ((bmp_off + bmp_bits + 7) / 8) > lco) {
+               if (cbo + (off + 7) / 8 > lco ||
+                   cbo + ((off + bits + 7) / 8) > lco) {
                        goto dirty_vol;
                }
 
-               __bitmap_set(Add2Ptr(buffer_le, roff), bmp_off, bmp_bits);
+               ntfs_bitmap_set_le(Add2Ptr(buffer_le, roff), off, bits);
                a_dirty = true;
                break;
 
        case ClearBitsInNonresidentBitMap:
-               bmp_off =
-                       le32_to_cpu(((struct BITMAP_RANGE *)data)->bitmap_off);
-               bmp_bits = le32_to_cpu(((struct BITMAP_RANGE *)data)->bits);
+               off = le32_to_cpu(((struct BITMAP_RANGE *)data)->bitmap_off);
+               bits = le32_to_cpu(((struct BITMAP_RANGE *)data)->bits);
 
-               if (cbo + (bmp_off + 7) / 8 > lco ||
-                   cbo + ((bmp_off + bmp_bits + 7) / 8) > lco) {
+               if (cbo + (off + 7) / 8 > lco ||
+                   cbo + ((off + bits + 7) / 8) > lco) {
                        goto dirty_vol;
                }
 
-               __bitmap_clear(Add2Ptr(buffer_le, roff), bmp_off, bmp_bits);
+               ntfs_bitmap_clear_le(Add2Ptr(buffer_le, roff), off, bits);
                a_dirty = true;
                break;
 
@@ -4771,6 +4750,12 @@ fake_attr:
                u16 roff = le16_to_cpu(attr->nres.run_off);
                CLST svcn = le64_to_cpu(attr->nres.svcn);
 
+               if (roff > t32) {
+                       kfree(oa->attr);
+                       oa->attr = NULL;
+                       goto fake_attr;
+               }
+
                err = run_unpack(&oa->run0, sbi, inode->i_ino, svcn,
                                 le64_to_cpu(attr->nres.evcn), svcn,
                                 Add2Ptr(attr, roff), t32 - roff);
@@ -4839,8 +4824,7 @@ next_dirty_page_vcn:
                goto out;
        }
        attr = oa->attr;
-       t64 = le64_to_cpu(attr->nres.alloc_size);
-       if (size > t64) {
+       if (size > le64_to_cpu(attr->nres.alloc_size)) {
                attr->nres.valid_size = attr->nres.data_size =
                        attr->nres.alloc_size = cpu_to_le64(size);
        }