Skip to content

Commit 04b43ea

Browse files
committed
Merge tag 'ubifs-for-linus-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs
Pull JFFS2, UBI and UBIFS updates from Richard Weinberger: "JFFS2: - Bug fix for rtime compression - Various cleanups UBI: - Cleanups for fastmap and wear leveling UBIFS: - Add support for FS_IOC_GETFSSYSFSPATH - Remove dead ioctl code - Fix UAF in ubifs_tnc_end_commit()" * tag 'ubifs-for-linus-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs: (25 commits) ubifs: Fix uninitialized use of err in ubifs_jnl_write_inode() jffs2: Prevent rtime decompress memory corruption jffs2: remove redundant check on outpos > pos fs: jffs2: Fix inconsistent indentation in jffs2_mark_node_obsolete jffs2: Correct some typos in comments jffs2: fix use of uninitialized variable jffs2: Use str_yes_no() helper function mtd: ubi: remove redundant check on bytes_left at end of function mtd: ubi: fix unreleased fwnode_handle in find_volume_fwnode() ubifs: authentication: Fix use-after-free in ubifs_tnc_end_commit ubi: fastmap: Fix duplicate slab cache names while attaching ubifs: xattr: remove unused anonymous enum ubifs: Reduce kfree() calls in ubifs_purge_xattrs() ubifs: Call iput(xino) only once in ubifs_purge_xattrs() ubi: wl: Close down wear-leveling before nand is suspended mtd: ubi: Rmove unused declaration in header file ubifs: Correct the total block count by deducting journal reservation ubifs: Convert to use ERR_CAST() ubifs: add support for FS_IOC_GETFSSYSFSPATH ubifs: remove unused ioctl flags GETFLAGS/SETFLAGS ...
2 parents e864eff + bcdcb11 commit 04b43ea

File tree

22 files changed

+96
-98
lines changed

22 files changed

+96
-98
lines changed

drivers/mtd/ubi/attach.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,7 +1447,7 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai,
14471447
return err;
14481448
}
14491449

1450-
static struct ubi_attach_info *alloc_ai(void)
1450+
static struct ubi_attach_info *alloc_ai(const char *slab_name)
14511451
{
14521452
struct ubi_attach_info *ai;
14531453

@@ -1461,7 +1461,7 @@ static struct ubi_attach_info *alloc_ai(void)
14611461
INIT_LIST_HEAD(&ai->alien);
14621462
INIT_LIST_HEAD(&ai->fastmap);
14631463
ai->volumes = RB_ROOT;
1464-
ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache",
1464+
ai->aeb_slab_cache = kmem_cache_create(slab_name,
14651465
sizeof(struct ubi_ainf_peb),
14661466
0, 0, NULL);
14671467
if (!ai->aeb_slab_cache) {
@@ -1491,7 +1491,7 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info **ai)
14911491

14921492
err = -ENOMEM;
14931493

1494-
scan_ai = alloc_ai();
1494+
scan_ai = alloc_ai("ubi_aeb_slab_cache_fastmap");
14951495
if (!scan_ai)
14961496
goto out;
14971497

@@ -1557,7 +1557,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
15571557
int err;
15581558
struct ubi_attach_info *ai;
15591559

1560-
ai = alloc_ai();
1560+
ai = alloc_ai("ubi_aeb_slab_cache");
15611561
if (!ai)
15621562
return -ENOMEM;
15631563

@@ -1575,7 +1575,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
15751575
if (err > 0 || mtd_is_eccerr(err)) {
15761576
if (err != UBI_NO_FASTMAP) {
15771577
destroy_ai(ai);
1578-
ai = alloc_ai();
1578+
ai = alloc_ai("ubi_aeb_slab_cache");
15791579
if (!ai)
15801580
return -ENOMEM;
15811581

@@ -1614,7 +1614,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
16141614
if (ubi->fm && ubi_dbg_chk_fastmap(ubi)) {
16151615
struct ubi_attach_info *scan_ai;
16161616

1617-
scan_ai = alloc_ai();
1617+
scan_ai = alloc_ai("ubi_aeb_slab_cache_dbg_chk_fastmap");
16181618
if (!scan_ai) {
16191619
err = -ENOMEM;
16201620
goto out_wl;

drivers/mtd/ubi/fastmap-wl.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,14 +346,27 @@ int ubi_wl_get_peb(struct ubi_device *ubi)
346346
* WL sub-system.
347347
*
348348
* @ubi: UBI device description object
349+
* @need_fill: whether to fill wear-leveling pool when no PEBs are found
349350
*/
350-
static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi)
351+
static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi,
352+
bool need_fill)
351353
{
352354
struct ubi_fm_pool *pool = &ubi->fm_wl_pool;
353355
int pnum;
354356

355-
if (pool->used == pool->size)
357+
if (pool->used == pool->size) {
358+
if (need_fill && !ubi->fm_work_scheduled) {
359+
/*
360+
* We cannot update the fastmap here because this
361+
* function is called in atomic context.
362+
* Let's fail here and refill/update it as soon as
363+
* possible.
364+
*/
365+
ubi->fm_work_scheduled = 1;
366+
schedule_work(&ubi->fm_work);
367+
}
356368
return NULL;
369+
}
357370

358371
pnum = pool->pebs[pool->used];
359372
return ubi->lookuptbl[pnum];
@@ -375,7 +388,7 @@ static bool need_wear_leveling(struct ubi_device *ubi)
375388
if (!ubi->used.rb_node)
376389
return false;
377390

378-
e = next_peb_for_wl(ubi);
391+
e = next_peb_for_wl(ubi, false);
379392
if (!e) {
380393
if (!ubi->free.rb_node)
381394
return false;

drivers/mtd/ubi/nvmem.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static int ubi_nvmem_reg_read(void *priv, unsigned int from,
5555
if (err)
5656
return err;
5757

58-
return bytes_left == 0 ? 0 : -EIO;
58+
return 0;
5959
}
6060

6161
static int ubi_nvmem_add(struct ubi_volume_info *vi)

drivers/mtd/ubi/ubi.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,7 @@ struct ubi_debug_info {
549549
* @peb_buf: a buffer of PEB size used for different purposes
550550
* @buf_mutex: protects @peb_buf
551551
* @ckvol_mutex: serializes static volume checking when opening
552+
* @wl_reboot_notifier: close all wear-leveling work before reboot
552553
*
553554
* @dbg: debugging information for this UBI device
554555
*/
@@ -651,6 +652,7 @@ struct ubi_device {
651652
void *peb_buf;
652653
struct mutex buf_mutex;
653654
struct mutex ckvol_mutex;
655+
struct notifier_block wl_reboot_notifier;
654656

655657
struct ubi_debug_info dbg;
656658
};
@@ -831,7 +833,6 @@ void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av);
831833
struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi,
832834
struct ubi_attach_info *ai);
833835
int ubi_attach(struct ubi_device *ubi, int force_scan);
834-
void ubi_destroy_ai(struct ubi_attach_info *ai);
835836

836837
/* vtbl.c */
837838
int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,

drivers/mtd/ubi/vmt.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,10 @@ static struct fwnode_handle *find_volume_fwnode(struct ubi_volume *vol)
143143
vol->vol_id != volid)
144144
continue;
145145

146+
fwnode_handle_put(fw_vols);
146147
return fw_vol;
147148
}
149+
fwnode_handle_put(fw_vols);
148150

149151
return NULL;
150152
}

drivers/mtd/ubi/wl.c

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
#include <linux/crc32.h>
9090
#include <linux/freezer.h>
9191
#include <linux/kthread.h>
92+
#include <linux/reboot.h>
9293
#include "ubi.h"
9394
#include "wl.h"
9495

@@ -127,6 +128,8 @@ static int self_check_in_wl_tree(const struct ubi_device *ubi,
127128
struct ubi_wl_entry *e, struct rb_root *root);
128129
static int self_check_in_pq(const struct ubi_device *ubi,
129130
struct ubi_wl_entry *e);
131+
static int ubi_wl_reboot_notifier(struct notifier_block *n,
132+
unsigned long state, void *cmd);
130133

131134
/**
132135
* wl_tree_add - add a wear-leveling entry to a WL RB-tree.
@@ -683,7 +686,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
683686
ubi_assert(!ubi->move_to_put);
684687

685688
#ifdef CONFIG_MTD_UBI_FASTMAP
686-
if (!next_peb_for_wl(ubi) ||
689+
if (!next_peb_for_wl(ubi, true) ||
687690
#else
688691
if (!ubi->free.rb_node ||
689692
#endif
@@ -846,7 +849,14 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
846849
goto out_not_moved;
847850
}
848851
if (err == MOVE_RETRY) {
849-
scrubbing = 1;
852+
/*
853+
* For source PEB:
854+
* 1. The scrubbing is set for scrub type PEB, it will
855+
* be put back into ubi->scrub list.
856+
* 2. Non-scrub type PEB will be put back into ubi->used
857+
* list.
858+
*/
859+
keep = 1;
850860
dst_leb_clean = 1;
851861
goto out_not_moved;
852862
}
@@ -1943,6 +1953,13 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
19431953
if (!ubi->ro_mode && !ubi->fm_disabled)
19441954
ubi_ensure_anchor_pebs(ubi);
19451955
#endif
1956+
1957+
if (!ubi->wl_reboot_notifier.notifier_call) {
1958+
ubi->wl_reboot_notifier.notifier_call = ubi_wl_reboot_notifier;
1959+
ubi->wl_reboot_notifier.priority = 1; /* Higher than MTD */
1960+
register_reboot_notifier(&ubi->wl_reboot_notifier);
1961+
}
1962+
19461963
return 0;
19471964

19481965
out_free:
@@ -1988,6 +2005,17 @@ void ubi_wl_close(struct ubi_device *ubi)
19882005
kfree(ubi->lookuptbl);
19892006
}
19902007

2008+
static int ubi_wl_reboot_notifier(struct notifier_block *n,
2009+
unsigned long state, void *cmd)
2010+
{
2011+
struct ubi_device *ubi;
2012+
2013+
ubi = container_of(n, struct ubi_device, wl_reboot_notifier);
2014+
ubi_wl_close(ubi);
2015+
2016+
return NOTIFY_DONE;
2017+
}
2018+
19912019
/**
19922020
* self_check_ec - make sure that the erase counter of a PEB is correct.
19932021
* @ubi: UBI device description object

drivers/mtd/ubi/wl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
static void update_fastmap_work_fn(struct work_struct *wrk);
66
static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root);
77
static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi);
8-
static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi);
8+
static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi,
9+
bool need_fill);
910
static bool need_wear_leveling(struct ubi_device *ubi);
1011
static void ubi_fastmap_close(struct ubi_device *ubi);
1112
static inline void ubi_fastmap_init(struct ubi_device *ubi, int *count)

fs/jffs2/compr_rtime.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ static int jffs2_rtime_decompress(unsigned char *data_in,
9595

9696
positions[value]=outpos;
9797
if (repeat) {
98+
if ((outpos + repeat) >= destlen) {
99+
return 1;
100+
}
98101
if (backoffs + repeat >= outpos) {
99102
while(repeat) {
100103
cpage_out[outpos++] = cpage_out[backoffs++];

fs/jffs2/compr_rubin.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -276,11 +276,6 @@ static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in,
276276

277277
end_rubin(&rs);
278278

279-
if (outpos > pos) {
280-
/* We failed */
281-
return -1;
282-
}
283-
284279
/* Tell the caller how much we managed to compress,
285280
* and how much space it took */
286281

fs/jffs2/erase.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,10 +338,9 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
338338
} while(--retlen);
339339
mtd_unpoint(c->mtd, jeb->offset, c->sector_size);
340340
if (retlen) {
341-
pr_warn("Newly-erased block contained word 0x%lx at offset 0x%08tx\n",
342-
*wordebuf,
343-
jeb->offset +
344-
c->sector_size-retlen * sizeof(*wordebuf));
341+
*bad_offset = jeb->offset + c->sector_size - retlen * sizeof(*wordebuf);
342+
pr_warn("Newly-erased block contained word 0x%lx at offset 0x%08x\n",
343+
*wordebuf, *bad_offset);
345344
return -EIO;
346345
}
347346
return 0;

0 commit comments

Comments
 (0)