Skip to content

Commit 763dede

Browse files
committed
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()
2 parents 762a9f2 + 3676f32 commit 763dede

File tree

6 files changed

+40
-10
lines changed

6 files changed

+40
-10
lines changed

drivers/mtd/ubi/fastmap-wl.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root)
3939
return victim;
4040
}
4141

42+
static inline void return_unused_peb(struct ubi_device *ubi,
43+
struct ubi_wl_entry *e)
44+
{
45+
wl_tree_add(e, &ubi->free);
46+
ubi->free_count++;
47+
}
48+
4249
/**
4350
* return_unused_pool_pebs - returns unused PEB to the free tree.
4451
* @ubi: UBI device description object
@@ -52,8 +59,7 @@ static void return_unused_pool_pebs(struct ubi_device *ubi,
5259

5360
for (i = pool->used; i < pool->size; i++) {
5461
e = ubi->lookuptbl[pool->pebs[i]];
55-
wl_tree_add(e, &ubi->free);
56-
ubi->free_count++;
62+
return_unused_peb(ubi, e);
5763
}
5864
}
5965

@@ -361,6 +367,11 @@ static void ubi_fastmap_close(struct ubi_device *ubi)
361367
return_unused_pool_pebs(ubi, &ubi->fm_pool);
362368
return_unused_pool_pebs(ubi, &ubi->fm_wl_pool);
363369

370+
if (ubi->fm_anchor) {
371+
return_unused_peb(ubi, ubi->fm_anchor);
372+
ubi->fm_anchor = NULL;
373+
}
374+
364375
if (ubi->fm) {
365376
for (i = 0; i < ubi->fm->used_blocks; i++)
366377
kfree(ubi->fm->e[i]);

drivers/mtd/ubi/ubi-media.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,6 @@ struct ubi_fm_volhdr {
498498
struct ubi_fm_eba {
499499
__be32 magic;
500500
__be32 reserved_pebs;
501-
__be32 pnum[0];
501+
__be32 pnum[];
502502
} __packed;
503503
#endif /* !__UBI_MEDIA_H__ */

drivers/mtd/ubi/wl.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1875,7 +1875,8 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
18751875
goto out_free;
18761876

18771877
#ifdef CONFIG_MTD_UBI_FASTMAP
1878-
ubi_ensure_anchor_pebs(ubi);
1878+
if (!ubi->ro_mode && !ubi->fm_disabled)
1879+
ubi_ensure_anchor_pebs(ubi);
18791880
#endif
18801881
return 0;
18811882

fs/ubifs/io.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ int ubifs_is_mapped(const struct ubifs_info *c, int lnum)
225225
int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
226226
int offs, int quiet, int must_chk_crc)
227227
{
228-
int err = -EINVAL, type, node_len;
228+
int err = -EINVAL, type, node_len, dump_node = 1;
229229
uint32_t crc, node_crc, magic;
230230
const struct ubifs_ch *ch = buf;
231231

@@ -278,10 +278,22 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
278278
out_len:
279279
if (!quiet)
280280
ubifs_err(c, "bad node length %d", node_len);
281+
if (type == UBIFS_DATA_NODE && node_len > UBIFS_DATA_NODE_SZ)
282+
dump_node = 0;
281283
out:
282284
if (!quiet) {
283285
ubifs_err(c, "bad node at LEB %d:%d", lnum, offs);
284-
ubifs_dump_node(c, buf);
286+
if (dump_node) {
287+
ubifs_dump_node(c, buf);
288+
} else {
289+
int safe_len = min3(node_len, c->leb_size - offs,
290+
(int)UBIFS_MAX_DATA_NODE_SZ);
291+
pr_err("\tprevent out-of-bounds memory access\n");
292+
pr_err("\ttruncated data node length %d\n", safe_len);
293+
pr_err("\tcorrupted data node:\n");
294+
print_hex_dump(KERN_ERR, "\t", DUMP_PREFIX_OFFSET, 32, 1,
295+
buf, safe_len, 0);
296+
}
285297
dump_stack();
286298
}
287299
return err;

fs/ubifs/journal.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,7 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode)
905905
ubifs_err(c, "dead directory entry '%s', error %d",
906906
xent->name, err);
907907
ubifs_ro_mode(c, err);
908+
kfree(xent);
908909
goto out_release;
909910
}
910911
ubifs_assert(c, ubifs_inode(xino)->xattr);

fs/ubifs/orphan.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum)
157157
int err = 0;
158158
ino_t xattr_inum;
159159
union ubifs_key key;
160-
struct ubifs_dent_node *xent;
160+
struct ubifs_dent_node *xent, *pxent = NULL;
161161
struct fscrypt_name nm = {0};
162162
struct ubifs_orphan *xattr_orphan;
163163
struct ubifs_orphan *orphan;
@@ -181,11 +181,16 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum)
181181
xattr_inum = le64_to_cpu(xent->inum);
182182

183183
xattr_orphan = orphan_add(c, xattr_inum, orphan);
184-
if (IS_ERR(xattr_orphan))
184+
if (IS_ERR(xattr_orphan)) {
185+
kfree(xent);
185186
return PTR_ERR(xattr_orphan);
187+
}
186188

189+
kfree(pxent);
190+
pxent = xent;
187191
key_read(c, &xent->key, &key);
188192
}
193+
kfree(pxent);
189194

190195
return 0;
191196
}
@@ -688,14 +693,14 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
688693

689694
ino_key_init(c, &key1, inum);
690695
err = ubifs_tnc_lookup(c, &key1, ino);
691-
if (err)
696+
if (err && err != -ENOENT)
692697
goto out_free;
693698

694699
/*
695700
* Check whether an inode can really get deleted.
696701
* linkat() with O_TMPFILE allows rebirth of an inode.
697702
*/
698-
if (ino->nlink == 0) {
703+
if (err == 0 && ino->nlink == 0) {
699704
dbg_rcvry("deleting orphaned inode %lu",
700705
(unsigned long)inum);
701706

0 commit comments

Comments
 (0)