diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-12-02 17:06:34 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-12-02 17:06:34 -0800 |
commit | e3a251e366e1a007c7ce7b2809b67f4dece6b17c (patch) | |
tree | c42ff533ba214975c683cafaab16d0bbf75d065a /fs/ubifs/tnc_commit.c | |
parent | 97eeb4d9d755605385fa329da9afa38729f3413c (diff) | |
parent | 6e78c01fde9023e0701f3af880c1fd9de6e4e8e3 (diff) |
Merge tag 'upstream-5.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs
Pull UBI/UBIFS/JFFS2 updates from Richard Weinberger:
"This pull request contains mostly fixes for UBI, UBIFS and JFFS2:
UBI:
- Fix a regression around producing a anchor PEB for fastmap.
Due to a change in our locking fastmap was unable to produce fresh
anchors an re-used the existing one a way to often.
UBIFS:
- Fixes for endianness. A few places blindly assumed little endian.
- Fix for a memory leak in the orphan code.
- Fix for a possible crash during a commit.
- Revert a wrong bugfix.
JFFS2:
- Revert a bad bugfix (false positive from a code checking tool)"
* tag 'upstream-5.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs:
Revert "jffs2: Fix possible null-pointer dereferences in jffs2_add_frag_to_fragtree()"
ubi: Fix producing anchor PEBs
ubifs: ubifs_tnc_start_commit: Fix OOB in layout_in_gaps
ubifs: do_kill_orphans: Fix a memory leak bug
Revert "ubifs: Fix memory leak bug in alloc_ubifs_info() error path"
ubifs: Fix type of sup->hash_algo
ubifs: Fixed missed le64_to_cpu() in journal
ubifs: Force prandom result to __le32
ubifs: Remove obsolete TODO from dfs_file_write()
ubi: Fix warning static is not at beginning of declaration
ubi: Print skip_check in ubi_dump_vol_info()
Diffstat (limited to 'fs/ubifs/tnc_commit.c')
-rw-r--r-- | fs/ubifs/tnc_commit.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c index a384a0f9ff32..234be1c4dc87 100644 --- a/fs/ubifs/tnc_commit.c +++ b/fs/ubifs/tnc_commit.c @@ -212,7 +212,7 @@ static int is_idx_node_in_use(struct ubifs_info *c, union ubifs_key *key, /** * layout_leb_in_gaps - layout index nodes using in-the-gaps method. * @c: UBIFS file-system description object - * @p: return LEB number here + * @p: return LEB number in @c->gap_lebs[p] * * This function lays out new index nodes for dirty znodes using in-the-gaps * method of TNC commit. @@ -221,7 +221,7 @@ static int is_idx_node_in_use(struct ubifs_info *c, union ubifs_key *key, * This function returns the number of index nodes written into the gaps, or a * negative error code on failure. */ -static int layout_leb_in_gaps(struct ubifs_info *c, int *p) +static int layout_leb_in_gaps(struct ubifs_info *c, int p) { struct ubifs_scan_leb *sleb; struct ubifs_scan_node *snod; @@ -236,7 +236,7 @@ static int layout_leb_in_gaps(struct ubifs_info *c, int *p) * filled, however we do not check there at present. */ return lnum; /* Error code */ - *p = lnum; + c->gap_lebs[p] = lnum; dbg_gc("LEB %d", lnum); /* * Scan the index LEB. We use the generic scan for this even though @@ -355,7 +355,7 @@ static int get_leb_cnt(struct ubifs_info *c, int cnt) */ static int layout_in_gaps(struct ubifs_info *c, int cnt) { - int err, leb_needed_cnt, written, *p; + int err, leb_needed_cnt, written, p = 0, old_idx_lebs, *gap_lebs; dbg_gc("%d znodes to write", cnt); @@ -364,9 +364,9 @@ static int layout_in_gaps(struct ubifs_info *c, int cnt) if (!c->gap_lebs) return -ENOMEM; - p = c->gap_lebs; + old_idx_lebs = c->lst.idx_lebs; do { - ubifs_assert(c, p < c->gap_lebs + c->lst.idx_lebs); + ubifs_assert(c, p < c->lst.idx_lebs); written = layout_leb_in_gaps(c, p); if (written < 0) { err = written; @@ -392,9 +392,29 @@ static int layout_in_gaps(struct ubifs_info *c, int cnt) leb_needed_cnt = get_leb_cnt(c, cnt); dbg_gc("%d znodes remaining, need %d LEBs, have %d", cnt, leb_needed_cnt, c->ileb_cnt); + /* + * Dynamically change the size of @c->gap_lebs to prevent + * oob, because @c->lst.idx_lebs could be increased by + * function @get_idx_gc_leb (called by layout_leb_in_gaps-> + * ubifs_find_dirty_idx_leb) during loop. Only enlarge + * @c->gap_lebs when needed. + * + */ + if (leb_needed_cnt > c->ileb_cnt && p >= old_idx_lebs && + old_idx_lebs < c->lst.idx_lebs) { + old_idx_lebs = c->lst.idx_lebs; + gap_lebs = krealloc(c->gap_lebs, sizeof(int) * + (old_idx_lebs + 1), GFP_NOFS); + if (!gap_lebs) { + kfree(c->gap_lebs); + c->gap_lebs = NULL; + return -ENOMEM; + } + c->gap_lebs = gap_lebs; + } } while (leb_needed_cnt > c->ileb_cnt); - *p = -1; + c->gap_lebs[p] = -1; return 0; } |