diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-01-18 16:58:38 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-01-18 16:58:38 -0500 |
commit | fb1d8e0e2c50f374cfc244564decfc3f0a336cb4 (patch) | |
tree | 8903198620726b46268e802b640e854fe78ab357 | |
parent | fa19a769f82fb9a5ca000b83cacd13fcaeda51ac (diff) | |
parent | 1cb51a15b576ee325d527726afff40947218fd5e (diff) |
Merge tag 'upstream-4.10-rc5' of git://git.infradead.org/linux-ubifs
Pull UBIFS fixes from Richard Weinberger:
"This contains fixes for UBIFS:
- a long standing issue in UBIFS journal replay code
- fallout from the merge window"
* tag 'upstream-4.10-rc5' of git://git.infradead.org/linux-ubifs:
ubifs: Fix journal replay wrt. xattr nodes
ubifs: remove redundant checks for encryption key
ubifs: allow encryption ioctls in compat mode
ubifs: add CONFIG_BLOCK dependency for encryption
ubifs: fix unencrypted journal write
ubifs: ensure zero err is returned on successful return
-rw-r--r-- | fs/ubifs/Kconfig | 2 | ||||
-rw-r--r-- | fs/ubifs/dir.c | 58 | ||||
-rw-r--r-- | fs/ubifs/ioctl.c | 3 | ||||
-rw-r--r-- | fs/ubifs/journal.c | 2 | ||||
-rw-r--r-- | fs/ubifs/tnc.c | 25 |
5 files changed, 32 insertions, 58 deletions
diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig index 0a908ae7af13..b0d0623c83ed 100644 --- a/fs/ubifs/Kconfig +++ b/fs/ubifs/Kconfig | |||
@@ -53,7 +53,7 @@ config UBIFS_ATIME_SUPPORT | |||
53 | 53 | ||
54 | config UBIFS_FS_ENCRYPTION | 54 | config UBIFS_FS_ENCRYPTION |
55 | bool "UBIFS Encryption" | 55 | bool "UBIFS Encryption" |
56 | depends on UBIFS_FS | 56 | depends on UBIFS_FS && BLOCK |
57 | select FS_ENCRYPTION | 57 | select FS_ENCRYPTION |
58 | default n | 58 | default n |
59 | help | 59 | help |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 1c5331ac9614..528369f3e472 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
@@ -390,16 +390,6 @@ static int do_tmpfile(struct inode *dir, struct dentry *dentry, | |||
390 | dbg_gen("dent '%pd', mode %#hx in dir ino %lu", | 390 | dbg_gen("dent '%pd', mode %#hx in dir ino %lu", |
391 | dentry, mode, dir->i_ino); | 391 | dentry, mode, dir->i_ino); |
392 | 392 | ||
393 | if (ubifs_crypt_is_encrypted(dir)) { | ||
394 | err = fscrypt_get_encryption_info(dir); | ||
395 | if (err) | ||
396 | return err; | ||
397 | |||
398 | if (!fscrypt_has_encryption_key(dir)) { | ||
399 | return -EPERM; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm); | 393 | err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm); |
404 | if (err) | 394 | if (err) |
405 | return err; | 395 | return err; |
@@ -741,17 +731,9 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir, | |||
741 | ubifs_assert(inode_is_locked(dir)); | 731 | ubifs_assert(inode_is_locked(dir)); |
742 | ubifs_assert(inode_is_locked(inode)); | 732 | ubifs_assert(inode_is_locked(inode)); |
743 | 733 | ||
744 | if (ubifs_crypt_is_encrypted(dir)) { | 734 | if (ubifs_crypt_is_encrypted(dir) && |
745 | if (!fscrypt_has_permitted_context(dir, inode)) | 735 | !fscrypt_has_permitted_context(dir, inode)) |
746 | return -EPERM; | 736 | return -EPERM; |
747 | |||
748 | err = fscrypt_get_encryption_info(inode); | ||
749 | if (err) | ||
750 | return err; | ||
751 | |||
752 | if (!fscrypt_has_encryption_key(inode)) | ||
753 | return -EPERM; | ||
754 | } | ||
755 | 737 | ||
756 | err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm); | 738 | err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm); |
757 | if (err) | 739 | if (err) |
@@ -1000,17 +982,6 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
1000 | if (err) | 982 | if (err) |
1001 | return err; | 983 | return err; |
1002 | 984 | ||
1003 | if (ubifs_crypt_is_encrypted(dir)) { | ||
1004 | err = fscrypt_get_encryption_info(dir); | ||
1005 | if (err) | ||
1006 | goto out_budg; | ||
1007 | |||
1008 | if (!fscrypt_has_encryption_key(dir)) { | ||
1009 | err = -EPERM; | ||
1010 | goto out_budg; | ||
1011 | } | ||
1012 | } | ||
1013 | |||
1014 | err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm); | 985 | err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm); |
1015 | if (err) | 986 | if (err) |
1016 | goto out_budg; | 987 | goto out_budg; |
@@ -1096,17 +1067,6 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry, | |||
1096 | return err; | 1067 | return err; |
1097 | } | 1068 | } |
1098 | 1069 | ||
1099 | if (ubifs_crypt_is_encrypted(dir)) { | ||
1100 | err = fscrypt_get_encryption_info(dir); | ||
1101 | if (err) | ||
1102 | goto out_budg; | ||
1103 | |||
1104 | if (!fscrypt_has_encryption_key(dir)) { | ||
1105 | err = -EPERM; | ||
1106 | goto out_budg; | ||
1107 | } | ||
1108 | } | ||
1109 | |||
1110 | err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm); | 1070 | err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm); |
1111 | if (err) | 1071 | if (err) |
1112 | goto out_budg; | 1072 | goto out_budg; |
@@ -1231,18 +1191,6 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry, | |||
1231 | goto out_inode; | 1191 | goto out_inode; |
1232 | } | 1192 | } |
1233 | 1193 | ||
1234 | err = fscrypt_get_encryption_info(inode); | ||
1235 | if (err) { | ||
1236 | kfree(sd); | ||
1237 | goto out_inode; | ||
1238 | } | ||
1239 | |||
1240 | if (!fscrypt_has_encryption_key(inode)) { | ||
1241 | kfree(sd); | ||
1242 | err = -EPERM; | ||
1243 | goto out_inode; | ||
1244 | } | ||
1245 | |||
1246 | ostr.name = sd->encrypted_path; | 1194 | ostr.name = sd->encrypted_path; |
1247 | ostr.len = disk_link.len; | 1195 | ostr.len = disk_link.len; |
1248 | 1196 | ||
diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c index 78d713644df3..da519ba205f6 100644 --- a/fs/ubifs/ioctl.c +++ b/fs/ubifs/ioctl.c | |||
@@ -217,6 +217,9 @@ long ubifs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
217 | case FS_IOC32_SETFLAGS: | 217 | case FS_IOC32_SETFLAGS: |
218 | cmd = FS_IOC_SETFLAGS; | 218 | cmd = FS_IOC_SETFLAGS; |
219 | break; | 219 | break; |
220 | case FS_IOC_SET_ENCRYPTION_POLICY: | ||
221 | case FS_IOC_GET_ENCRYPTION_POLICY: | ||
222 | break; | ||
220 | default: | 223 | default: |
221 | return -ENOIOCTLCMD; | 224 | return -ENOIOCTLCMD; |
222 | } | 225 | } |
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index a459211a1c21..294519b98874 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c | |||
@@ -744,6 +744,7 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, | |||
744 | 744 | ||
745 | } else { | 745 | } else { |
746 | data->compr_size = 0; | 746 | data->compr_size = 0; |
747 | out_len = compr_len; | ||
747 | } | 748 | } |
748 | 749 | ||
749 | dlen = UBIFS_DATA_NODE_SZ + out_len; | 750 | dlen = UBIFS_DATA_NODE_SZ + out_len; |
@@ -1319,6 +1320,7 @@ static int truncate_data_node(const struct ubifs_info *c, const struct inode *in | |||
1319 | dn->compr_type = cpu_to_le16(compr_type); | 1320 | dn->compr_type = cpu_to_le16(compr_type); |
1320 | dn->size = cpu_to_le32(*new_len); | 1321 | dn->size = cpu_to_le32(*new_len); |
1321 | *new_len = UBIFS_DATA_NODE_SZ + out_len; | 1322 | *new_len = UBIFS_DATA_NODE_SZ + out_len; |
1323 | err = 0; | ||
1322 | out: | 1324 | out: |
1323 | kfree(buf); | 1325 | kfree(buf); |
1324 | return err; | 1326 | return err; |
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 74ae2de949df..709aa098dd46 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c | |||
@@ -34,6 +34,11 @@ | |||
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include "ubifs.h" | 35 | #include "ubifs.h" |
36 | 36 | ||
37 | static int try_read_node(const struct ubifs_info *c, void *buf, int type, | ||
38 | int len, int lnum, int offs); | ||
39 | static int fallible_read_node(struct ubifs_info *c, const union ubifs_key *key, | ||
40 | struct ubifs_zbranch *zbr, void *node); | ||
41 | |||
37 | /* | 42 | /* |
38 | * Returned codes of 'matches_name()' and 'fallible_matches_name()' functions. | 43 | * Returned codes of 'matches_name()' and 'fallible_matches_name()' functions. |
39 | * @NAME_LESS: name corresponding to the first argument is less than second | 44 | * @NAME_LESS: name corresponding to the first argument is less than second |
@@ -402,7 +407,19 @@ static int tnc_read_hashed_node(struct ubifs_info *c, struct ubifs_zbranch *zbr, | |||
402 | return 0; | 407 | return 0; |
403 | } | 408 | } |
404 | 409 | ||
405 | err = ubifs_tnc_read_node(c, zbr, node); | 410 | if (c->replaying) { |
411 | err = fallible_read_node(c, &zbr->key, zbr, node); | ||
412 | /* | ||
413 | * When the node was not found, return -ENOENT, 0 otherwise. | ||
414 | * Negative return codes stay as-is. | ||
415 | */ | ||
416 | if (err == 0) | ||
417 | err = -ENOENT; | ||
418 | else if (err == 1) | ||
419 | err = 0; | ||
420 | } else { | ||
421 | err = ubifs_tnc_read_node(c, zbr, node); | ||
422 | } | ||
406 | if (err) | 423 | if (err) |
407 | return err; | 424 | return err; |
408 | 425 | ||
@@ -2857,7 +2874,11 @@ struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c, | |||
2857 | if (fname_len(nm) > 0) { | 2874 | if (fname_len(nm) > 0) { |
2858 | if (err) { | 2875 | if (err) { |
2859 | /* Handle collisions */ | 2876 | /* Handle collisions */ |
2860 | err = resolve_collision(c, key, &znode, &n, nm); | 2877 | if (c->replaying) |
2878 | err = fallible_resolve_collision(c, key, &znode, &n, | ||
2879 | nm, 0); | ||
2880 | else | ||
2881 | err = resolve_collision(c, key, &znode, &n, nm); | ||
2861 | dbg_tnc("rc returned %d, znode %p, n %d", | 2882 | dbg_tnc("rc returned %d, znode %p, n %d", |
2862 | err, znode, n); | 2883 | err, znode, n); |
2863 | if (unlikely(err < 0)) | 2884 | if (unlikely(err < 0)) |