Skip to content

Commit 966859b

Browse files
committed
Merge tag 'upstream-4.13-rc1' of git://git.infradead.org/linux-ubifs
Pull UBIFS updates from Richard Weinberger: - Updates and fixes for the file encryption mode - Minor improvements - Random fixes * tag 'upstream-4.13-rc1' of git://git.infradead.org/linux-ubifs: ubifs: Set double hash cookie also for RENAME_EXCHANGE ubifs: Massage assert in ubifs_xattr_set() wrt. init_xattrs ubifs: Don't leak kernel memory to the MTD ubifs: Change gfp flags in page allocation for bulk read ubifs: Fix oops when remounting with no_bulk_read. ubifs: Fail commit if TNC is obviously inconsistent ubifs: allow userspace to map mounts to volumes ubifs: Wire-up statx() support ubifs: Remove dead code from ubifs_get_link() ubifs: Massage debug prints wrt. fscrypt ubifs: Add assert to dent_key_init() ubifs: Fix unlink code wrt. double hash lookups ubifs: Fix data node size for truncating uncompressed nodes ubifs: Don't encrypt special files on creation ubifs: Fix memory leak in RENAME_WHITEOUT error path in do_rename ubifs: Fix inode data budget in ubifs_mknod ubifs: Correctly evict xattr inodes ubifs: Unexport ubifs_inode_slab ubifs: don't bother checking for encryption key in ->mmap() ubifs: require key for truncate(2) of encrypted file
2 parents e37a07e + a666443 commit 966859b

File tree

10 files changed

+218
-85
lines changed

10 files changed

+218
-85
lines changed

fs/ubifs/crypto.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,13 @@ static int ubifs_crypt_get_context(struct inode *inode, void *ctx, size_t len)
99
static int ubifs_crypt_set_context(struct inode *inode, const void *ctx,
1010
size_t len, void *fs_data)
1111
{
12+
/*
13+
* Creating an encryption context is done unlocked since we
14+
* operate on a new inode which is not visible to other users
15+
* at this point. So, no need to check whether inode is locked.
16+
*/
1217
return ubifs_xattr_set(inode, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT,
13-
ctx, len, 0);
18+
ctx, len, 0, false);
1419
}
1520

1621
static bool ubifs_crypt_empty_dir(struct inode *inode)

fs/ubifs/dir.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
143143
case S_IFBLK:
144144
case S_IFCHR:
145145
inode->i_op = &ubifs_file_inode_operations;
146+
encrypted = false;
146147
break;
147148
default:
148149
BUG();
@@ -1061,7 +1062,6 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry,
10611062
int sz_change;
10621063
int err, devlen = 0;
10631064
struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
1064-
.new_ino_d = ALIGN(devlen, 8),
10651065
.dirtied_ino = 1 };
10661066
struct fscrypt_name nm;
10671067

@@ -1079,6 +1079,7 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry,
10791079
devlen = ubifs_encode_dev(dev, rdev);
10801080
}
10811081

1082+
req.new_ino_d = ALIGN(devlen, 8);
10821083
err = ubifs_budget_space(c, &req);
10831084
if (err) {
10841085
kfree(dev);
@@ -1396,17 +1397,14 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
13961397

13971398
dev = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS);
13981399
if (!dev) {
1399-
ubifs_release_budget(c, &req);
1400-
ubifs_release_budget(c, &ino_req);
1401-
return -ENOMEM;
1400+
err = -ENOMEM;
1401+
goto out_release;
14021402
}
14031403

14041404
err = do_tmpfile(old_dir, old_dentry, S_IFCHR | WHITEOUT_MODE, &whiteout);
14051405
if (err) {
1406-
ubifs_release_budget(c, &req);
1407-
ubifs_release_budget(c, &ino_req);
14081406
kfree(dev);
1409-
return err;
1407+
goto out_release;
14101408
}
14111409

14121410
whiteout->i_state |= I_LINKABLE;
@@ -1494,12 +1492,10 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
14941492

14951493
err = ubifs_budget_space(c, &wht_req);
14961494
if (err) {
1497-
ubifs_release_budget(c, &req);
1498-
ubifs_release_budget(c, &ino_req);
14991495
kfree(whiteout_ui->data);
15001496
whiteout_ui->data_len = 0;
15011497
iput(whiteout);
1502-
return err;
1498+
goto out_release;
15031499
}
15041500

15051501
inc_nlink(whiteout);
@@ -1554,6 +1550,7 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
15541550
iput(whiteout);
15551551
}
15561552
unlock_4_inodes(old_dir, new_dir, new_inode, whiteout);
1553+
out_release:
15571554
ubifs_release_budget(c, &ino_req);
15581555
ubifs_release_budget(c, &req);
15591556
fscrypt_free_filename(&old_nm);
@@ -1647,6 +1644,21 @@ int ubifs_getattr(const struct path *path, struct kstat *stat,
16471644
struct ubifs_inode *ui = ubifs_inode(inode);
16481645

16491646
mutex_lock(&ui->ui_mutex);
1647+
1648+
if (ui->flags & UBIFS_APPEND_FL)
1649+
stat->attributes |= STATX_ATTR_APPEND;
1650+
if (ui->flags & UBIFS_COMPR_FL)
1651+
stat->attributes |= STATX_ATTR_COMPRESSED;
1652+
if (ui->flags & UBIFS_CRYPT_FL)
1653+
stat->attributes |= STATX_ATTR_ENCRYPTED;
1654+
if (ui->flags & UBIFS_IMMUTABLE_FL)
1655+
stat->attributes |= STATX_ATTR_IMMUTABLE;
1656+
1657+
stat->attributes_mask |= (STATX_ATTR_APPEND |
1658+
STATX_ATTR_COMPRESSED |
1659+
STATX_ATTR_ENCRYPTED |
1660+
STATX_ATTR_IMMUTABLE);
1661+
16501662
generic_fillattr(inode, stat);
16511663
stat->blksize = UBIFS_BLOCK_SIZE;
16521664
stat->size = ui->ui_size;

fs/ubifs/file.c

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,7 @@ static int ubifs_do_bulk_read(struct ubifs_info *c, struct bu_info *bu,
735735
int err, page_idx, page_cnt, ret = 0, n = 0;
736736
int allocate = bu->buf ? 0 : 1;
737737
loff_t isize;
738+
gfp_t ra_gfp_mask = readahead_gfp_mask(mapping) & ~__GFP_FS;
738739

739740
err = ubifs_tnc_get_bu_keys(c, bu);
740741
if (err)
@@ -796,8 +797,7 @@ static int ubifs_do_bulk_read(struct ubifs_info *c, struct bu_info *bu,
796797

797798
if (page_offset > end_index)
798799
break;
799-
page = find_or_create_page(mapping, page_offset,
800-
GFP_NOFS | __GFP_COLD);
800+
page = find_or_create_page(mapping, page_offset, ra_gfp_mask);
801801
if (!page)
802802
break;
803803
if (!PageUptodate(page))
@@ -1284,6 +1284,14 @@ int ubifs_setattr(struct dentry *dentry, struct iattr *attr)
12841284
if (err)
12851285
return err;
12861286

1287+
if (ubifs_crypt_is_encrypted(inode) && (attr->ia_valid & ATTR_SIZE)) {
1288+
err = fscrypt_get_encryption_info(inode);
1289+
if (err)
1290+
return err;
1291+
if (!fscrypt_has_encryption_key(inode))
1292+
return -ENOKEY;
1293+
}
1294+
12871295
if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size < inode->i_size)
12881296
/* Truncation to a smaller size */
12891297
err = do_truncation(c, inode, attr);
@@ -1607,15 +1615,6 @@ static const struct vm_operations_struct ubifs_file_vm_ops = {
16071615
static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma)
16081616
{
16091617
int err;
1610-
struct inode *inode = file->f_mapping->host;
1611-
1612-
if (ubifs_crypt_is_encrypted(inode)) {
1613-
err = fscrypt_get_encryption_info(inode);
1614-
if (err)
1615-
return -EACCES;
1616-
if (!fscrypt_has_encryption_key(inode))
1617-
return -ENOKEY;
1618-
}
16191618

16201619
err = generic_file_mmap(file, vma);
16211620
if (err)
@@ -1698,12 +1697,6 @@ static const char *ubifs_get_link(struct dentry *dentry,
16981697

16991698
pstr.name[pstr.len] = '\0';
17001699

1701-
// XXX this probably won't happen anymore...
1702-
if (pstr.name[0] == '\0') {
1703-
fscrypt_fname_free_buffer(&pstr);
1704-
return ERR_PTR(-ENOENT);
1705-
}
1706-
17071700
set_delayed_call(done, kfree_link, pstr.name);
17081701
return pstr.name;
17091702
}

fs/ubifs/journal.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -549,8 +549,6 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
549549
struct ubifs_ino_node *ino;
550550
union ubifs_key dent_key, ino_key;
551551

552-
//dbg_jnl("ino %lu, dent '%.*s', data len %d in dir ino %lu",
553-
// inode->i_ino, nm->len, nm->name, ui->data_len, dir->i_ino);
554552
ubifs_assert(mutex_is_locked(&host_ui->ui_mutex));
555553

556554
dlen = UBIFS_DENT_NODE_SZ + fname_len(nm) + 1;
@@ -574,7 +572,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
574572
/* Make sure to also account for extended attributes */
575573
len += host_ui->data_len;
576574

577-
dent = kmalloc(len, GFP_NOFS);
575+
dent = kzalloc(len, GFP_NOFS);
578576
if (!dent)
579577
return -ENOMEM;
580578

@@ -585,7 +583,10 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
585583

586584
if (!xent) {
587585
dent->ch.node_type = UBIFS_DENT_NODE;
588-
dent_key_init(c, &dent_key, dir->i_ino, nm);
586+
if (nm->hash)
587+
dent_key_init_hash(c, &dent_key, dir->i_ino, nm->hash);
588+
else
589+
dent_key_init(c, &dent_key, dir->i_ino, nm);
589590
} else {
590591
dent->ch.node_type = UBIFS_XENT_NODE;
591592
xent_key_init(c, &dent_key, dir->i_ino, nm);
@@ -629,7 +630,10 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
629630
kfree(dent);
630631

631632
if (deletion) {
632-
err = ubifs_tnc_remove_nm(c, &dent_key, nm);
633+
if (nm->hash)
634+
err = ubifs_tnc_remove_dh(c, &dent_key, nm->minor_hash);
635+
else
636+
err = ubifs_tnc_remove_nm(c, &dent_key, nm);
633637
if (err)
634638
goto out_ro;
635639
err = ubifs_add_dirt(c, lnum, dlen);
@@ -950,9 +954,6 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir,
950954
int twoparents = (fst_dir != snd_dir);
951955
void *p;
952956

953-
//dbg_jnl("dent '%pd' in dir ino %lu between dent '%pd' in dir ino %lu",
954-
// fst_dentry, fst_dir->i_ino, snd_dentry, snd_dir->i_ino);
955-
956957
ubifs_assert(ubifs_inode(fst_dir)->data_len == 0);
957958
ubifs_assert(ubifs_inode(snd_dir)->data_len == 0);
958959
ubifs_assert(mutex_is_locked(&ubifs_inode(fst_dir)->ui_mutex));
@@ -967,7 +968,7 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir,
967968
if (twoparents)
968969
len += plen;
969970

970-
dent1 = kmalloc(len, GFP_NOFS);
971+
dent1 = kzalloc(len, GFP_NOFS);
971972
if (!dent1)
972973
return -ENOMEM;
973974

@@ -984,6 +985,7 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir,
984985
dent1->nlen = cpu_to_le16(fname_len(snd_nm));
985986
memcpy(dent1->name, fname_name(snd_nm), fname_len(snd_nm));
986987
dent1->name[fname_len(snd_nm)] = '\0';
988+
set_dent_cookie(c, dent1);
987989
zero_dent_node_unused(dent1);
988990
ubifs_prep_grp_node(c, dent1, dlen1, 0);
989991

@@ -996,6 +998,7 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir,
996998
dent2->nlen = cpu_to_le16(fname_len(fst_nm));
997999
memcpy(dent2->name, fname_name(fst_nm), fname_len(fst_nm));
9981000
dent2->name[fname_len(fst_nm)] = '\0';
1001+
set_dent_cookie(c, dent2);
9991002
zero_dent_node_unused(dent2);
10001003
ubifs_prep_grp_node(c, dent2, dlen2, 0);
10011004

@@ -1094,8 +1097,6 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
10941097
int move = (old_dir != new_dir);
10951098
struct ubifs_inode *uninitialized_var(new_ui);
10961099

1097-
//dbg_jnl("dent '%pd' in dir ino %lu to dent '%pd' in dir ino %lu",
1098-
// old_dentry, old_dir->i_ino, new_dentry, new_dir->i_ino);
10991100
ubifs_assert(ubifs_inode(old_dir)->data_len == 0);
11001101
ubifs_assert(ubifs_inode(new_dir)->data_len == 0);
11011102
ubifs_assert(mutex_is_locked(&ubifs_inode(old_dir)->ui_mutex));
@@ -1117,7 +1118,7 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
11171118
len = aligned_dlen1 + aligned_dlen2 + ALIGN(ilen, 8) + ALIGN(plen, 8);
11181119
if (move)
11191120
len += plen;
1120-
dent = kmalloc(len, GFP_NOFS);
1121+
dent = kzalloc(len, GFP_NOFS);
11211122
if (!dent)
11221123
return -ENOMEM;
11231124

@@ -1298,7 +1299,9 @@ static int truncate_data_node(const struct ubifs_info *c, const struct inode *in
12981299
goto out;
12991300
}
13001301

1301-
if (compr_type != UBIFS_COMPR_NONE) {
1302+
if (compr_type == UBIFS_COMPR_NONE) {
1303+
out_len = *new_len;
1304+
} else {
13021305
err = ubifs_decompress(c, &dn->data, dlen, buf, &out_len, compr_type);
13031306
if (err)
13041307
goto out;
@@ -1485,9 +1488,6 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host,
14851488
int sync = IS_DIRSYNC(host);
14861489
struct ubifs_inode *host_ui = ubifs_inode(host);
14871490

1488-
//dbg_jnl("host %lu, xattr ino %lu, name '%s', data len %d",
1489-
// host->i_ino, inode->i_ino, nm->name,
1490-
// ubifs_inode(inode)->data_len);
14911491
ubifs_assert(inode->i_nlink == 0);
14921492
ubifs_assert(mutex_is_locked(&host_ui->ui_mutex));
14931493

@@ -1500,7 +1500,7 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host,
15001500
hlen = host_ui->data_len + UBIFS_INO_NODE_SZ;
15011501
len = aligned_xlen + UBIFS_INO_NODE_SZ + ALIGN(hlen, 8);
15021502

1503-
xent = kmalloc(len, GFP_NOFS);
1503+
xent = kzalloc(len, GFP_NOFS);
15041504
if (!xent)
15051505
return -ENOMEM;
15061506

@@ -1607,7 +1607,7 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode,
16071607
aligned_len1 = ALIGN(len1, 8);
16081608
aligned_len = aligned_len1 + ALIGN(len2, 8);
16091609

1610-
ino = kmalloc(aligned_len, GFP_NOFS);
1610+
ino = kzalloc(aligned_len, GFP_NOFS);
16111611
if (!ino)
16121612
return -ENOMEM;
16131613

fs/ubifs/key.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ static inline void dent_key_init(const struct ubifs_info *c,
162162
uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
163163

164164
ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
165+
ubifs_assert(!nm->hash && !nm->minor_hash);
165166
key->u32[0] = inum;
166167
key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS);
167168
}

fs/ubifs/super.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
#define UBIFS_KMALLOC_OK (128*1024)
4646

4747
/* Slab cache for UBIFS inodes */
48-
struct kmem_cache *ubifs_inode_slab;
48+
static struct kmem_cache *ubifs_inode_slab;
4949

5050
/* UBIFS TNC shrinker description */
5151
static struct shrinker ubifs_shrinker_info = {
@@ -446,6 +446,8 @@ static int ubifs_show_options(struct seq_file *s, struct dentry *root)
446446
ubifs_compr_name(c->mount_opts.compr_type));
447447
}
448448

449+
seq_printf(s, ",ubi=%d,vol=%d", c->vi.ubi_num, c->vi.vol_id);
450+
449451
return 0;
450452
}
451453

@@ -931,6 +933,7 @@ enum {
931933
Opt_chk_data_crc,
932934
Opt_no_chk_data_crc,
933935
Opt_override_compr,
936+
Opt_ignore,
934937
Opt_err,
935938
};
936939

@@ -942,6 +945,8 @@ static const match_table_t tokens = {
942945
{Opt_chk_data_crc, "chk_data_crc"},
943946
{Opt_no_chk_data_crc, "no_chk_data_crc"},
944947
{Opt_override_compr, "compr=%s"},
948+
{Opt_ignore, "ubi=%s"},
949+
{Opt_ignore, "vol=%s"},
945950
{Opt_err, NULL},
946951
};
947952

@@ -1042,6 +1047,8 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
10421047
c->default_compr = c->mount_opts.compr_type;
10431048
break;
10441049
}
1050+
case Opt_ignore:
1051+
break;
10451052
default:
10461053
{
10471054
unsigned long flag;
@@ -1869,8 +1876,10 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
18691876
bu_init(c);
18701877
else {
18711878
dbg_gen("disable bulk-read");
1879+
mutex_lock(&c->bu_mutex);
18721880
kfree(c->bu.buf);
18731881
c->bu.buf = NULL;
1882+
mutex_unlock(&c->bu_mutex);
18741883
}
18751884

18761885
ubifs_assert(c->lst.taken_empty_lebs > 0);

0 commit comments

Comments
 (0)