Skip to content

Commit 163c3e3

Browse files
committed
Merge tag 'for-linus-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs
Pull JFFS2, UBI and UBIFS updates from Richard Weinberger: "JFFS2: - Fix for a corner case while mounting - Fix for an use-after-free issue UBI: - Fix for a memory load while attaching - Don't produce an anchor PEB with fastmap being disabled UBIFS: - Fix for orphan inode logic - Spelling fixes - New mount option to specify filesystem version" * tag 'for-linus-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs: jffs2: fix UAF problem jffs2: fix jffs2 mounting failure ubifs: Fix wrong orphan node deletion in ubifs_jnl_update|rename ubi: fastmap: Free fastmap next anchor peb during detach ubi: fastmap: Don't produce the initial next anchor PEB when fastmap is disabled ubifs: misc.h: delete a duplicated word ubifs: add option to specify version for new file systems
2 parents 4bcf69e + 798b734 commit 163c3e3

File tree

9 files changed

+43
-10
lines changed

9 files changed

+43
-10
lines changed

drivers/mtd/ubi/fastmap-wl.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,11 @@ static void ubi_fastmap_close(struct ubi_device *ubi)
381381
ubi->fm_anchor = NULL;
382382
}
383383

384+
if (ubi->fm_next_anchor) {
385+
return_unused_peb(ubi, ubi->fm_next_anchor);
386+
ubi->fm_next_anchor = NULL;
387+
}
388+
384389
if (ubi->fm) {
385390
for (i = 0; i < ubi->fm->used_blocks; i++)
386391
kfree(ubi->fm->e[i]);

drivers/mtd/ubi/wl.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,8 @@ static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
10861086
if (!err) {
10871087
spin_lock(&ubi->wl_lock);
10881088

1089-
if (!ubi->fm_next_anchor && e->pnum < UBI_FM_MAX_START) {
1089+
if (!ubi->fm_disabled && !ubi->fm_next_anchor &&
1090+
e->pnum < UBI_FM_MAX_START) {
10901091
/* Abort anchor production, if needed it will be
10911092
* enabled again in the wear leveling started below.
10921093
*/

fs/jffs2/dir.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,10 +590,14 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry)
590590
int ret;
591591
uint32_t now = JFFS2_NOW();
592592

593+
mutex_lock(&f->sem);
593594
for (fd = f->dents ; fd; fd = fd->next) {
594-
if (fd->ino)
595+
if (fd->ino) {
596+
mutex_unlock(&f->sem);
595597
return -ENOTEMPTY;
598+
}
596599
}
600+
mutex_unlock(&f->sem);
597601

598602
ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,
599603
dentry->d_name.len, f, now);

fs/jffs2/scan.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,8 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
261261
}
262262
#endif
263263
if (c->nr_erasing_blocks) {
264-
if ( !c->used_size && ((c->nr_free_blocks+empty_blocks+bad_blocks)!= c->nr_blocks || bad_blocks == c->nr_blocks) ) {
264+
if (!c->used_size && !c->unchecked_size &&
265+
((c->nr_free_blocks+empty_blocks+bad_blocks) != c->nr_blocks || bad_blocks == c->nr_blocks)) {
265266
pr_notice("Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");
266267
pr_notice("empty_blocks %d, bad_blocks %d, c->nr_blocks %d\n",
267268
empty_blocks, bad_blocks, c->nr_blocks);

fs/ubifs/journal.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
539539
const struct fscrypt_name *nm, const struct inode *inode,
540540
int deletion, int xent)
541541
{
542-
int err, dlen, ilen, len, lnum, ino_offs, dent_offs;
542+
int err, dlen, ilen, len, lnum, ino_offs, dent_offs, orphan_added = 0;
543543
int aligned_dlen, aligned_ilen, sync = IS_DIRSYNC(dir);
544544
int last_reference = !!(deletion && inode->i_nlink == 0);
545545
struct ubifs_inode *ui = ubifs_inode(inode);
@@ -630,6 +630,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
630630
goto out_finish;
631631
}
632632
ui->del_cmtno = c->cmt_no;
633+
orphan_added = 1;
633634
}
634635

635636
err = write_head(c, BASEHD, dent, len, &lnum, &dent_offs, sync);
@@ -702,7 +703,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
702703
kfree(dent);
703704
out_ro:
704705
ubifs_ro_mode(c, err);
705-
if (last_reference)
706+
if (orphan_added)
706707
ubifs_delete_orphan(c, inode->i_ino);
707708
finish_reservation(c);
708709
return err;
@@ -1218,7 +1219,7 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
12181219
void *p;
12191220
union ubifs_key key;
12201221
struct ubifs_dent_node *dent, *dent2;
1221-
int err, dlen1, dlen2, ilen, lnum, offs, len;
1222+
int err, dlen1, dlen2, ilen, lnum, offs, len, orphan_added = 0;
12221223
int aligned_dlen1, aligned_dlen2, plen = UBIFS_INO_NODE_SZ;
12231224
int last_reference = !!(new_inode && new_inode->i_nlink == 0);
12241225
int move = (old_dir != new_dir);
@@ -1334,6 +1335,7 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
13341335
goto out_finish;
13351336
}
13361337
new_ui->del_cmtno = c->cmt_no;
1338+
orphan_added = 1;
13371339
}
13381340

13391341
err = write_head(c, BASEHD, dent, len, &lnum, &offs, sync);
@@ -1415,7 +1417,7 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
14151417
release_head(c, BASEHD);
14161418
out_ro:
14171419
ubifs_ro_mode(c, err);
1418-
if (last_reference)
1420+
if (orphan_added)
14191421
ubifs_delete_orphan(c, new_inode->i_ino);
14201422
out_finish:
14211423
finish_reservation(c);

fs/ubifs/misc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ static inline const char *ubifs_compr_name(struct ubifs_info *c, int compr_type)
121121
* ubifs_wbuf_sync - synchronize write-buffer.
122122
* @wbuf: write-buffer to synchronize
123123
*
124-
* This is the same as as 'ubifs_wbuf_sync_nolock()' but it does not assume
124+
* This is the same as 'ubifs_wbuf_sync_nolock()' but it does not assume
125125
* that the write-buffer is already locked.
126126
*/
127127
static inline int ubifs_wbuf_sync(struct ubifs_wbuf *wbuf)

fs/ubifs/sb.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ static int create_default_filesystem(struct ubifs_info *c)
174174
tmp64 = (long long)max_buds * c->leb_size;
175175
if (big_lpt)
176176
sup_flags |= UBIFS_FLG_BIGLPT;
177-
sup_flags |= UBIFS_FLG_DOUBLE_HASH;
177+
if (ubifs_default_version > 4)
178+
sup_flags |= UBIFS_FLG_DOUBLE_HASH;
178179

179180
if (ubifs_authenticated(c)) {
180181
sup_flags |= UBIFS_FLG_AUTHENTICATION;
@@ -200,7 +201,7 @@ static int create_default_filesystem(struct ubifs_info *c)
200201
sup->jhead_cnt = cpu_to_le32(DEFAULT_JHEADS_CNT);
201202
sup->fanout = cpu_to_le32(DEFAULT_FANOUT);
202203
sup->lsave_cnt = cpu_to_le32(c->lsave_cnt);
203-
sup->fmt_version = cpu_to_le32(UBIFS_FORMAT_VERSION);
204+
sup->fmt_version = cpu_to_le32(ubifs_default_version);
204205
sup->time_gran = cpu_to_le32(DEFAULT_TIME_GRAN);
205206
if (c->mount_opts.override_compr)
206207
sup->default_compr = cpu_to_le16(c->mount_opts.compr_type);

fs/ubifs/super.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,24 @@
2626
#include <linux/writeback.h>
2727
#include "ubifs.h"
2828

29+
static int ubifs_default_version_set(const char *val, const struct kernel_param *kp)
30+
{
31+
int n = 0, ret;
32+
33+
ret = kstrtoint(val, 10, &n);
34+
if (ret != 0 || n < 4 || n > UBIFS_FORMAT_VERSION)
35+
return -EINVAL;
36+
return param_set_int(val, kp);
37+
}
38+
39+
static const struct kernel_param_ops ubifs_default_version_ops = {
40+
.set = ubifs_default_version_set,
41+
.get = param_get_int,
42+
};
43+
44+
int ubifs_default_version = UBIFS_FORMAT_VERSION;
45+
module_param_cb(default_version, &ubifs_default_version_ops, &ubifs_default_version, 0600);
46+
2947
/*
3048
* Maximum amount of memory we may 'kmalloc()' without worrying that we are
3149
* allocating too much.

fs/ubifs/ubifs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,6 +1504,7 @@ extern const struct file_operations ubifs_dir_operations;
15041504
extern const struct inode_operations ubifs_dir_inode_operations;
15051505
extern const struct inode_operations ubifs_symlink_inode_operations;
15061506
extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT];
1507+
extern int ubifs_default_version;
15071508

15081509
/* auth.c */
15091510
static inline int ubifs_authenticated(const struct ubifs_info *c)

0 commit comments

Comments
 (0)