This pull request contains fixes for UBI and UBIFS:

- Fix for memory leaks around UBIFS orphan handling
 - Fix for memory leaks around UBI fastmap
 - Remove zero-length array from ubi-media.h
 - Fix for TNC lookup in UBIFS orphan code
 -----BEGIN PGP SIGNATURE-----
 
 iQJKBAABCAA0FiEEdgfidid8lnn52cLTZvlZhesYu8EFAl6McBEWHHJpY2hhcmRA
 c2lnbWEtc3Rhci5hdAAKCRBm+VmF6xi7wbxzD/0RXX1RmnLUtyWvurC+Ge+wJR9k
 T/LvMrT5TAUpbXsDTFmbhQJiWlnu70Pg2Gcqr+yXz/YboAr1+G0G3SonC1TYWNEe
 8aGsWMGeuiB1GTfrGJgyj3M/YxRUYHgRz75mUXZ0kQkraWYbIuKDpudsSAVcLV5Q
 jO0JQeZmaCB0w3pvaP1CpXEl9+CXnCAnEoheUgAjC9THUPYeAvI3mRbrDJL50Ine
 9PDAkP++LtYKRKS0tMhlDtbrjoFWMySmvOG6t7nkWhdj7IdLxCZuYgCV5CvUUiuv
 oBglozfzBEPp2sA4NlSghEg3zedrGSauDL/Ns3djPmpSWNJIuE5Q8bHZGO9msqR9
 MDoPTuSirY3L4ARGpG6rXc0holGq9NniQpa1ArnWnSUtkIjz22dT1V41dEumquxm
 PganYebBWe3tjSmSc8Jm1xNKscwTPYr6kBApLcDWaxdASD56Q95raAVNJLkP/kKz
 USb6ZTHunyZQALgqKFgFMc8Nm8Eyu+sXikQscYgR0vJsYy0gaQy52/F3UG2gBpjP
 9ULoHTilWU6cx07JdawgJNLfgj37ov3wlM5rW1G50TP7GpzAYlzPl7atozbyogii
 WeRA0AwM8LHcTggseqOtA3B8606giVlk5Iw2YJ7DkK1ArSAncThbb2rtm/PPyPWv
 JdG2bHXj3PnzSQfMDw==
 =RpJX
 -----END PGP SIGNATURE-----

Merge tag 'for-linus-5.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs

Pull UBI and UBIFS updates from Richard Weinberger:

 - Fix for memory leaks around UBIFS orphan handling

 - Fix for memory leaks around UBI fastmap

 - Remove zero-length array from ubi-media.h

 - Fix for TNC lookup in UBIFS orphan code

* tag 'for-linus-5.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs:
  ubi: ubi-media.h: Replace zero-length array with flexible-array member
  ubifs: Fix out-of-bounds memory access caused by abnormal value of node_len
  ubi: fastmap: Only produce the initial anchor PEB when fastmap is used
  ubi: fastmap: Free unused fastmap anchor peb during detach
  ubifs: ubifs_add_orphan: Fix a memory leak bug
  ubifs: ubifs_jnl_write_inode: Fix a memory leak bug
  ubifs: Fix ubifs_tnc_lookup() usage in do_kill_orphans()
This commit is contained in:
Linus Torvalds 2020-04-07 12:40:56 -07:00
commit 763dede1b2
6 changed files with 40 additions and 10 deletions

View File

@ -39,6 +39,13 @@ static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root)
return victim;
}
static inline void return_unused_peb(struct ubi_device *ubi,
struct ubi_wl_entry *e)
{
wl_tree_add(e, &ubi->free);
ubi->free_count++;
}
/**
* return_unused_pool_pebs - returns unused PEB to the free tree.
* @ubi: UBI device description object
@ -52,8 +59,7 @@ static void return_unused_pool_pebs(struct ubi_device *ubi,
for (i = pool->used; i < pool->size; i++) {
e = ubi->lookuptbl[pool->pebs[i]];
wl_tree_add(e, &ubi->free);
ubi->free_count++;
return_unused_peb(ubi, e);
}
}
@ -361,6 +367,11 @@ static void ubi_fastmap_close(struct ubi_device *ubi)
return_unused_pool_pebs(ubi, &ubi->fm_pool);
return_unused_pool_pebs(ubi, &ubi->fm_wl_pool);
if (ubi->fm_anchor) {
return_unused_peb(ubi, ubi->fm_anchor);
ubi->fm_anchor = NULL;
}
if (ubi->fm) {
for (i = 0; i < ubi->fm->used_blocks; i++)
kfree(ubi->fm->e[i]);

View File

@ -498,6 +498,6 @@ struct ubi_fm_volhdr {
struct ubi_fm_eba {
__be32 magic;
__be32 reserved_pebs;
__be32 pnum[0];
__be32 pnum[];
} __packed;
#endif /* !__UBI_MEDIA_H__ */

View File

@ -1875,7 +1875,8 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
goto out_free;
#ifdef CONFIG_MTD_UBI_FASTMAP
ubi_ensure_anchor_pebs(ubi);
if (!ubi->ro_mode && !ubi->fm_disabled)
ubi_ensure_anchor_pebs(ubi);
#endif
return 0;

View File

@ -225,7 +225,7 @@ int ubifs_is_mapped(const struct ubifs_info *c, int lnum)
int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
int offs, int quiet, int must_chk_crc)
{
int err = -EINVAL, type, node_len;
int err = -EINVAL, type, node_len, dump_node = 1;
uint32_t crc, node_crc, magic;
const struct ubifs_ch *ch = buf;
@ -278,10 +278,22 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
out_len:
if (!quiet)
ubifs_err(c, "bad node length %d", node_len);
if (type == UBIFS_DATA_NODE && node_len > UBIFS_DATA_NODE_SZ)
dump_node = 0;
out:
if (!quiet) {
ubifs_err(c, "bad node at LEB %d:%d", lnum, offs);
ubifs_dump_node(c, buf);
if (dump_node) {
ubifs_dump_node(c, buf);
} else {
int safe_len = min3(node_len, c->leb_size - offs,
(int)UBIFS_MAX_DATA_NODE_SZ);
pr_err("\tprevent out-of-bounds memory access\n");
pr_err("\ttruncated data node length %d\n", safe_len);
pr_err("\tcorrupted data node:\n");
print_hex_dump(KERN_ERR, "\t", DUMP_PREFIX_OFFSET, 32, 1,
buf, safe_len, 0);
}
dump_stack();
}
return err;

View File

@ -905,6 +905,7 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode)
ubifs_err(c, "dead directory entry '%s', error %d",
xent->name, err);
ubifs_ro_mode(c, err);
kfree(xent);
goto out_release;
}
ubifs_assert(c, ubifs_inode(xino)->xattr);

View File

@ -157,7 +157,7 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum)
int err = 0;
ino_t xattr_inum;
union ubifs_key key;
struct ubifs_dent_node *xent;
struct ubifs_dent_node *xent, *pxent = NULL;
struct fscrypt_name nm = {0};
struct ubifs_orphan *xattr_orphan;
struct ubifs_orphan *orphan;
@ -181,11 +181,16 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum)
xattr_inum = le64_to_cpu(xent->inum);
xattr_orphan = orphan_add(c, xattr_inum, orphan);
if (IS_ERR(xattr_orphan))
if (IS_ERR(xattr_orphan)) {
kfree(xent);
return PTR_ERR(xattr_orphan);
}
kfree(pxent);
pxent = xent;
key_read(c, &xent->key, &key);
}
kfree(pxent);
return 0;
}
@ -688,14 +693,14 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
ino_key_init(c, &key1, inum);
err = ubifs_tnc_lookup(c, &key1, ino);
if (err)
if (err && err != -ENOENT)
goto out_free;
/*
* Check whether an inode can really get deleted.
* linkat() with O_TMPFILE allows rebirth of an inode.
*/
if (ino->nlink == 0) {
if (err == 0 && ino->nlink == 0) {
dbg_rcvry("deleting orphaned inode %lu",
(unsigned long)inum);