Merge tag 'ntfs3_for_7.1' of https://github.com/Paragon-Software-Group/linux-ntfs3
Merge commit. Changes below are compared with the first parent: a5e1c3b6.
Changes
11 files changed · +202 −73
| File | Status | Add | Del | Content |
|---|---|---|---|---|
| fs/ntfs3/Makefile | modified | +20 | −0 | View file |
| fs/ntfs3/attrib.c | modified | +22 | −1 | View file |
| fs/ntfs3/frecord.c | modified | +27 | −22 | View file |
| fs/ntfs3/fslog.c | modified | +13 | −3 | View file |
| fs/ntfs3/fsntfs.c | modified | +2 | −2 | View file |
| fs/ntfs3/index.c | modified | +50 | −27 | View file |
| fs/ntfs3/inode.c | modified | +10 | −5 | View file |
| fs/ntfs3/ntfs_fs.h | modified | +0 | −3 | View file |
| fs/ntfs3/run.c | modified | +15 | −3 | View file |
| fs/ntfs3/super.c | modified | +42 | −6 | View file |
| fs/ntfs3/xattr.c | modified | +1 | −1 | View file |
Only the first 600 diff lines are shown. Download the complete patch.
fs/ntfs3/Makefile
View filediff --git a/fs/ntfs3/Makefile b/fs/ntfs3/Makefile
index 279701b..53bf2c1 100644
--- a/fs/ntfs3/Makefile
+++ b/fs/ntfs3/Makefile
@@ -3,6 +3,26 @@
# Makefile for the ntfs3 filesystem support.
#
+# Subset of W=1 warnings
+subdir-ccflags-y += -Wextra -Wunused -Wno-unused-parameter
+subdir-ccflags-y += -Wmissing-declarations
+subdir-ccflags-y += -Wmissing-format-attribute
+subdir-ccflags-y += -Wmissing-prototypes
+subdir-ccflags-y += -Wold-style-definition
+subdir-ccflags-y += -Wmissing-include-dirs
+condflags := \
+ $(call cc-option, -Wunused-but-set-variable) \
+ $(call cc-option, -Wunused-const-variable) \
+ $(call cc-option, -Wpacked-not-aligned) \
+ $(call cc-option, -Wstringop-truncation) \
+ $(call cc-option, -Wmaybe-uninitialized)
+subdir-ccflags-y += $(condflags)
+# The following turn off the warnings enabled by -Wextra
+subdir-ccflags-y += -Wno-missing-field-initializers
+subdir-ccflags-y += -Wno-sign-compare
+subdir-ccflags-y += -Wno-type-limits
+subdir-ccflags-y += -Wno-shift-negative-value
+
# to check robot warnings
ccflags-y += -Wint-to-pointer-cast \
$(call cc-option,-Wunused-but-set-variable,-Wunused-const-variable) \
fs/ntfs3/attrib.c
View filediff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c
index 6cb9bc5..e61c5bf 100644
--- a/fs/ntfs3/attrib.c
+++ b/fs/ntfs3/attrib.c
@@ -173,7 +173,7 @@ int attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run,
if (err == -ENOSPC && pre) {
pre = 0;
- if (*pre_alloc)
+ if (pre_alloc)
*pre_alloc = 0;
continue;
}
@@ -1152,6 +1152,21 @@ again:
if (err)
goto out;
}
+
+ if (vcn0 < svcn || evcn1 <= vcn0) {
+ struct ATTRIB *attr2;
+
+ attr2 = ni_find_attr(ni, attr_b, &le_b, ATTR_DATA, NULL,
+ 0, &vcn0, &mi);
+ if (!attr2) {
+ err = -EINVAL;
+ goto out;
+ }
+ err = attr_load_runs(attr2, ni, run, NULL);
+ if (err)
+ goto out;
+ }
+
da = false; /* no delalloc for compressed file. */
}
@@ -1576,6 +1591,12 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr,
u64 from = vbo[i] & ~(u64)(PAGE_SIZE - 1);
u64 to = min(from + PAGE_SIZE, wof_size);
+ if (from >= wof_size) {
+ _ntfs_bad_inode(&ni->vfs_inode);
+ err = -EINVAL;
+ goto out1;
+ }
+
err = attr_load_runs_range(ni, ATTR_DATA, WOF_NAME,
ARRAY_SIZE(WOF_NAME), run,
from, to);
fs/ntfs3/frecord.c
View filediff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
index 2e901d0..7b035da 100644
--- a/fs/ntfs3/frecord.c
+++ b/fs/ntfs3/frecord.c
@@ -1852,27 +1852,31 @@ enum REPARSE_SIGN ni_parse_reparse(struct ntfs_inode *ni, struct ATTRIB *attr,
return REPARSE_LINK;
}
-static struct page *ntfs_lock_new_page(struct address_space *mapping,
- pgoff_t index, gfp_t gfp)
+static struct folio *ntfs_lock_new_page(struct address_space *mapping,
+ pgoff_t index, gfp_t gfp)
{
- struct folio *folio = __filemap_get_folio(
- mapping, index, FGP_LOCK | FGP_ACCESSED | FGP_CREAT, gfp);
- struct page *page;
+ struct folio *folio = __filemap_get_folio(mapping, index,
+ FGP_LOCK | FGP_ACCESSED | FGP_CREAT, gfp);
if (IS_ERR(folio))
- return ERR_CAST(folio);
+ return folio;
- if (!folio_test_uptodate(folio))
- return folio_file_page(folio, index);
+ if (!folio_test_uptodate(folio)) {
+ struct page *page = folio_file_page(folio, index);
+
+ if (IS_ERR(page))
+ return ERR_CAST(page);
+ return page_folio(page);
+ }
/* Use a temporary page to avoid data corruption */
folio_unlock(folio);
folio_put(folio);
- page = alloc_page(gfp);
- if (!page)
+ folio = folio_alloc(gfp, 0);
+ if (!folio)
return ERR_PTR(-ENOMEM);
- __SetPageLocked(page);
- return page;
+ __folio_set_locked(folio);
+ return folio;
}
/*
@@ -1894,6 +1898,7 @@ int ni_read_folio_cmpr(struct ntfs_inode *ni, struct folio *folio)
u32 i, idx, frame_size, pages_per_frame;
gfp_t gfp_mask;
struct page *pg;
+ struct folio *f;
if (vbo >= i_size_read(&ni->vfs_inode)) {
folio_zero_range(folio, 0, folio_size(folio));
@@ -1929,12 +1934,12 @@ int ni_read_folio_cmpr(struct ntfs_inode *ni, struct folio *folio)
if (i == idx)
continue;
- pg = ntfs_lock_new_page(mapping, index, gfp_mask);
- if (IS_ERR(pg)) {
- err = PTR_ERR(pg);
+ f = ntfs_lock_new_page(mapping, index, gfp_mask);
+ if (IS_ERR(f)) {
+ err = PTR_ERR(f);
goto out1;
}
- pages[i] = pg;
+ pages[i] = &f->page;
}
ni_lock(ni);
@@ -2023,18 +2028,18 @@ int ni_decompress_file(struct ntfs_inode *ni)
}
for (i = 0; i < pages_per_frame; i++, index++) {
- struct page *pg;
+ struct folio *f;
- pg = ntfs_lock_new_page(mapping, index, gfp_mask);
- if (IS_ERR(pg)) {
+ f = ntfs_lock_new_page(mapping, index, gfp_mask);
+ if (IS_ERR(f)) {
while (i--) {
unlock_page(pages[i]);
put_page(pages[i]);
}
- err = PTR_ERR(pg);
+ err = PTR_ERR(f);
goto out;
}
- pages[i] = pg;
+ pages[i] = &f->page;
}
err = ni_read_frame(ni, vbo, pages, pages_per_frame, 1);
@@ -3262,7 +3267,7 @@ int ni_allocate_da_blocks(struct ntfs_inode *ni)
*/
int ni_allocate_da_blocks_locked(struct ntfs_inode *ni)
{
- int err;
+ int err = 0;
if (!ni->file.run_da.count)
return 0;
fs/ntfs3/fslog.c
View filediff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c
index 272e452..acfa18b 100644
--- a/fs/ntfs3/fslog.c
+++ b/fs/ntfs3/fslog.c
@@ -45,10 +45,10 @@ struct CLIENT_REC {
__le16 seq_num; // 0x14:
u8 align[6]; // 0x16:
__le32 name_bytes; // 0x1C: In bytes.
- __le16 name[32]; // 0x20: Name of client.
+ __le16 name[64]; // 0x20: Name of client.
};
-static_assert(sizeof(struct CLIENT_REC) == 0x60);
+static_assert(sizeof(struct CLIENT_REC) == 0xa0);
/* Two copies of these will exist at the beginning of the log file */
struct RESTART_AREA {
@@ -2791,13 +2791,14 @@ static inline bool check_file_record(const struct MFT_REC *rec,
u16 fn = le16_to_cpu(rec->rhdr.fix_num);
u16 ao = le16_to_cpu(rec->attr_off);
u32 rs = sbi->record_size;
+ u32 used = le32_to_cpu(rec->used);
/* Check the file record header for consistency. */
if (rec->rhdr.sign != NTFS_FILE_SIGNATURE ||
fo > (SECTOR_SIZE - ((rs >> SECTOR_SHIFT) + 1) * sizeof(short)) ||
(fn - 1) * SECTOR_SIZE != rs || ao < MFTRECORD_FIXUP_OFFSET_1 ||
ao > sbi->record_size - SIZEOF_RESIDENT || !is_rec_inuse(rec) ||
- le32_to_cpu(rec->total) != rs) {
+ le32_to_cpu(rec->total) != rs || used > rs || used < ao) {
return false;
}
@@ -2809,6 +2810,15 @@ static inline bool check_file_record(const struct MFT_REC *rec,
return false;
}
+ /*
+ * The do_action() handlers compute memmove lengths as
+ * "rec->used - <offset of validated attr>", which underflows when
+ * rec->used is smaller than the attribute walk reached. At this
+ * point attr is the ATTR_END marker; rec->used must cover it.
+ */
+ if (used < PtrOffset(rec, attr) + sizeof(attr->type))
+ return false;
+
return true;
}
fs/ntfs3/fsntfs.c
View filediff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c
index 0df2aa8..d043475 100644
--- a/fs/ntfs3/fsntfs.c
+++ b/fs/ntfs3/fsntfs.c
@@ -1440,8 +1440,8 @@ int ntfs_write_bh(struct ntfs_sb_info *sbi, struct NTFS_RECORD_HEADER *rhdr,
u16 fo = le16_to_cpu(rhdr->fix_off);
u16 fn = le16_to_cpu(rhdr->fix_num);
u32 idx;
- __le16 *fixup;
- __le16 sample;
+ __le16 *fixup = NULL;
+ __le16 sample = cpu_to_le16(-1u);
if ((fo & 1) || fo + fn * sizeof(short) > SECTOR_SIZE || !fn-- ||
fn * SECTOR_SIZE > bytes) {
fs/ntfs3/index.c
View filediff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c
index 97f06c2..5344b29 100644
--- a/fs/ntfs3/index.c
+++ b/fs/ntfs3/index.c
@@ -714,10 +714,10 @@ static bool fnd_is_empty(struct ntfs_fnd *fnd)
*/
static struct NTFS_DE *hdr_find_e(const struct ntfs_index *indx,
const struct INDEX_HDR *hdr, const void *key,
- size_t key_len, const void *ctx, int *diff)
+ size_t key_len, const void *ctx, int *diff,
+ NTFS_CMP_FUNC cmp)
{
struct NTFS_DE *e, *found = NULL;
- NTFS_CMP_FUNC cmp = indx->cmp;
int min_idx = 0, mid_idx, max_idx = 0;
int diff2;
int table_size = 8;
@@ -727,9 +727,6 @@ static struct NTFS_DE *hdr_find_e(const struct ntfs_index *indx,
u32 total = le32_to_cpu(hdr->total);
u16 offs[128];
- if (unlikely(!cmp))
- return NULL;
-
fill_table:
if (end > total)
return NULL;
@@ -800,7 +797,8 @@ binary_search:
static struct NTFS_DE *hdr_insert_de(const struct ntfs_index *indx,
struct INDEX_HDR *hdr,
const struct NTFS_DE *de,
- struct NTFS_DE *before, const void *ctx)
+ struct NTFS_DE *before, const void *ctx,
+ NTFS_CMP_FUNC cmp)
{
int diff;
size_t off = PtrOffset(hdr, before);
@@ -823,7 +821,7 @@ static struct NTFS_DE *hdr_insert_de(const struct ntfs_index *indx,
}
/* No insert point is applied. Get it manually. */
before = hdr_find_e(indx, hdr, de + 1, le16_to_cpu(de->key_size), ctx,
- &diff);
+ &diff, cmp);
if (!before)
return NULL;
off = PtrOffset(hdr, before);
@@ -915,10 +913,6 @@ int indx_init(struct ntfs_index *indx, struct ntfs_sb_info *sbi,
init_rwsem(&indx->run_lock);
- indx->cmp = get_cmp_func(root);
- if (!indx->cmp)
- goto out;
-
return 0;
out:
@@ -1141,6 +1135,7 @@ int indx_find(struct ntfs_index *indx, struct ntfs_inode *ni,
int err;
struct NTFS_DE *e;
struct indx_node *node;
+ NTFS_CMP_FUNC cmp;
if (!root)
root = indx_get_root(&ni->dir, ni, NULL, NULL);
@@ -1150,10 +1145,16 @@ int indx_find(struct ntfs_index *indx, struct ntfs_inode *ni,
return -EINVAL;
}
+ cmp = get_cmp_func(root);
+ if (unlikely(!cmp)) {
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
+
/* Check cache. */
e = fnd->level ? fnd->de[fnd->level - 1] : fnd->root_de;
if (e && !de_is_last(e) &&
- !(*indx->cmp)(key, key_len, e + 1, le16_to_cpu(e->key_size), ctx)) {
+ !(*cmp)(key, key_len, e + 1, le16_to_cpu(e->key_size), ctx)) {
*entry = e;
*diff = 0;
return 0;
@@ -1163,7 +1164,7 @@ int indx_find(struct ntfs_index *indx, struct ntfs_inode *ni,
fnd_clear(fnd);
/* Lookup entry that is <= to the search value. */
- e = hdr_find_e(indx, &root->ihdr, key, key_len, ctx, diff);
+ e = hdr_find_e(indx, &root->ihdr, key, key_len, ctx, diff, cmp);
if (!e)
return -EINVAL;
@@ -1183,7 +1184,7 @@ int indx_find(struct ntfs_index *indx, struct ntfs_inode *ni,
/* Lookup entry that is <= to the search value. */
e = hdr_find_e(indx, &node->index->ihdr, key, key_len, ctx,
- diff);
+ diff, cmp);
if (!e) {
put_indx_node(node);
return -EINVAL;
@@ -1481,6 +1482,7 @@ out1:
run_deallocate(sbi, &run, false);
out:
+ run_close(&run);
return err;
}
@@ -1585,7 +1587,7 @@ out1:
static int indx_insert_into_root(struct ntfs_index *indx, struct ntfs_inode *ni,
const struct NTFS_DE *new_de,
struct NTFS_DE *root_de, const void *ctx,
- struct ntfs_fnd *fnd, bool undo)
+ struct ntfs_fnd *fnd, bool undo, NTFS_CMP_FUNC cmp)
{
int err = 0;
struct NTFS_DE *e, *e0, *re;
@@ -1626,7 +1628,7 @@ static int indx_insert_into_root(struct ntfs_index *indx, struct ntfs_inode *ni,
if ((undo || asize + ds_root < sbi->max_bytes_per_attr) &&
mi_resize_attr(mi, attr, ds_root)) {
hdr->total = cpu_to_le32(hdr_total + ds_root);
- e = hdr_insert_de(indx, hdr, new_de, root_de, ctx);
+ e = hdr_insert_de(indx, hdr, new_de, root_de, ctx, cmp);
WARN_ON(!e);
fnd_clear(fnd);
fnd->root_de = e;
@@ -1767,7 +1769,7 @@ static int indx_insert_into_root(struct ntfs_index *indx, struct ntfs_inode *ni,
* Now root is a parent for new index buffer.
* Insert NewEntry a new buffer.
*/
- e = hdr_insert_de(indx, hdr, new_de, NULL, ctx);
+ e = hdr_insert_de(indx, hdr, new_de, NULL, ctx, cmp);
if (!e) {
err = -EINVAL;
goto out_put_n;
@@ -1797,7 +1799,7 @@ out_free_root:
static int
indx_insert_into_buffer(struct ntfs_index *indx, struct ntfs_inode *ni,
struct INDEX_ROOT *root, const struct NTFS_DE *new_de,
- const void *ctx, int level, struct ntfs_fnd *fnd)
+ const void *ctx, int level, struct ntfs_fnd *fnd, NTFS_CMP_FUNC cmp)
{
int err;
const struct NTFS_DE *sp;
@@ -1814,7 +1816,7 @@ indx_insert_into_buffer(struct ntfs_index *indx, struct ntfs_inode *ni,
/* Try the most easy case. */
e = fnd->level - 1 == level ? fnd->de[level] : NULL;
- e = hdr_insert_de(indx, hdr1, new_de, e, ctx);
+ e = hdr_insert_de(indx, hdr1, new_de, e, ctx, cmp);
fnd->de[level] = e;
if (e) {
/* Just write updated index into disk. */
@@ -1891,12 +1893,12 @@ indx_insert_into_buffer(struct ntfs_index *indx, struct ntfs_inode *ni,
* (depending on sp <=> new_de).
*/
hdr_insert_de(indx,
- (*indx->cmp)(new_de + 1, le16_to_cpu(new_de->key_size),
+ (*cmp)(new_de + 1, le16_to_cpu(new_de->key_size),
up_e + 1, le16_to_cpu(up_e->key_size),
ctx) < 0 ?
hdr2 :
hdr1,
- new_de, NULL, ctx);
+ new_de, NULL, ctx, cmp);
indx_mark_used(indx, ni, new_vbn >> indx->idx2vbn_bits);
@@ -1911,14 +1913,14 @@ indx_insert_into_buffer(struct ntfs_index *indx, struct ntfs_inode *ni,
*/
if (!level) {
/* Insert in root. */
- err = indx_insert_into_root(indx, ni, up_e, NULL, ctx, fnd, 0);
+ err = indx_insert_into_root(indx, ni, up_e, NULL, ctx, fnd, 0, cmp);
} else {
/*
* The target buffer's parent is another index buffer.
* TODO: Remove recursion.
*/
err = indx_insert_into_buffer(indx, ni, root, up_e, ctx,
- level - 1, fnd);
+ level - 1, fnd, cmp);
}
if (err) {
@@ -1952,6 +1954,7 @@ int indx_insert_entry(struct ntfs_index *indx, struct ntfs_inode *ni,
struct NTFS_DE *e;
struct ntfs_fnd *fnd_a = NULL;
struct INDEX_ROOT *root;
+ NTFS_CMP_FUNC cmp;
if (!fnd) {
fnd_a = fnd_get();
@@ -1968,6 +1971,12 @@ int indx_insert_entry(struct ntfs_index *indx, struct ntfs_inode *ni,
goto out;
}
+ cmp = get_cmp_func(root);
+ if (unlikely(!cmp)) {
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
+
if (fnd_is_empty(fnd)) {
/*
* Find the spot the tree where we want to
@@ -1991,13 +2000,13 @@ int indx_insert_entry(struct ntfs_index *indx, struct ntfs_inode *ni,
* new entry into it.
*/
err = indx_insert_into_root(indx, ni, new_de, fnd->root_de, ctx,
- fnd, undo);
+ fnd, undo, cmp);
} else {
/*
* Found a leaf buffer, so we'll insert the new entry into it.
*/
err = indx_insert_into_buffer(indx, ni, root, new_de, ctx,
- fnd->level - 1, fnd);
+ fnd->level - 1, fnd, cmp);
}
indx->version += 1;
@@ -2291,6 +2300,7 @@ int indx_delete_entry(struct ntfs_index *indx, struct ntfs_inode *ni,
u32 e_size, root_size, new_root_size;
size_t trim_bit;
const struct INDEX_NAMES *in;
+ NTFS_CMP_FUNC cmp;
fnd = fnd_get();
if (!fnd) {
@@ -2310,6 +2320,12 @@ int indx_delete_entry(struct ntfs_index *indx, struct ntfs_inode *ni,
goto out;
}
+ cmp = get_cmp_func(root);
+ if (unlikely(!cmp)) {
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
+
/* Locate the entry to remove. */
err = indx_find(indx, ni, root, key, key_len, ctx, &diff, &e, fnd);
if (err)
@@ -2376,9 +2392,9 @@ int indx_delete_entry(struct ntfs_index *indx, struct ntfs_inode *ni,
err = level ? indx_insert_into_buffer(indx, ni, root,
re, ctx,
fnd->level - 1,
- fnd) :
+ fnd, cmp) :
indx_insert_into_root(indx, ni, re, e,
- ctx, fnd, 0);
+ ctx, fnd, 0, cmp);
kfree(re);
if (err)
@@ -2673,6 +2689,7 @@ int indx_update_dup(struct ntfs_inode *ni, struct ntfs_sb_info *sbi,
struct INDEX_ROOT *root;
struct mft_inode *mi;
struct ntfs_index *indx = &ni->dir;
+ NTFS_CMP_FUNC cmp;
fnd = fnd_get();
if (!fnd)
@@ -2684,6 +2701,12 @@ int indx_update_dup(struct ntfs_inode *ni, struct ntfs_sb_info *sbi,
goto out;
}
+ cmp = get_cmp_func(root);
+ if (unlikely(!cmp)) {
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
+
/* Find entry in directory. */
err = indx_find(indx, ni, root, fname, fname_full_size(fname), sbi,
&diff, &e, fnd);
fs/ntfs3/inode.c
View filediff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
index a5d9e37..42af1ab 100644
--- a/fs/ntfs3/inode.c
+++ b/fs/ntfs3/inode.c
@@ -432,6 +432,11 @@ end_enum:
ni->mi.dirty = true;
}
+ if (!links) {
+ err = -EINVAL;
+ goto out;
+ }
+
set_nlink(inode, links);
if (S_ISDIR(mode)) {
@@ -773,6 +778,11 @@ static int ntfs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
return err;
}
+ if (!clen) {
+ /* broken file? */
+ return -EINVAL;
+ }
+
if (lcn == EOF_LCN) {
/* request out of file. */
if (flags & IOMAP_REPORT) {
@@ -806,11 +816,6 @@ static int ntfs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
return 0;
}
- if (!clen) {
- /* broken file? */
- return -EINVAL;
- }
-
iomap->bdev = inode->i_sb->s_bdev;
iomap->offset = offset;
iomap->length = ((loff_t)clen << cluster_bits) - off;
fs/ntfs3/ntfs_fs.h
View filediff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
index 56e608d..bbf3b6a 100644
--- a/fs/ntfs3/ntfs_fs.h
+++ b/fs/ntfs3/ntfs_fs.h
@@ -196,9 +196,6 @@ struct ntfs_index {
struct rw_semaphore run_lock;
size_t version; /* increment each change */
- /*TODO: Remove 'cmp'. */
- NTFS_CMP_FUNC cmp;
-
u8 index_bits; // log2(root->index_block_size)
u8 idx2vbn_bits; // log2(root->index_block_clst)
u8 vbn2vbo_bits; // index_block_size < cluster? 9 : cluster_bits
fs/ntfs3/run.c
View filediff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
index c0324cd..1ce7d92 100644
--- a/fs/ntfs3/run.c
+++ b/fs/ntfs3/run.c
@@ -1008,6 +1008,9 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
if (size_size > sizeof(len))
return -EINVAL;
+ if (run_buf + size_size > run_last)
+ return -EINVAL;
+
len = run_unpack_s64(run_buf, size_size, 0);
/* Skip size_size. */
run_buf += size_size;
@@ -1020,6 +1023,9 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
else if (offset_size <= sizeof(s64)) {
s64 dlcn;
+ if (run_buf + offset_size > run_last)
+ return -EINVAL;
This diff is incomplete. Download the complete patch.
fs/ntfs3/super.c
View fileThis diff is incomplete. Download the complete patch.
fs/ntfs3/xattr.c
View fileThis diff is incomplete. Download the complete patch.