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:
commit
763dede1b2
|
@ -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]);
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -1875,6 +1875,7 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
|
|||
goto out_free;
|
||||
|
||||
#ifdef CONFIG_MTD_UBI_FASTMAP
|
||||
if (!ubi->ro_mode && !ubi->fm_disabled)
|
||||
ubi_ensure_anchor_pebs(ubi);
|
||||
#endif
|
||||
return 0;
|
||||
|
|
|
@ -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);
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue