diff options
author | Eric Biggers <ebiggers@google.com> | 2016-09-15 17:25:55 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2016-09-15 17:25:55 -0400 |
commit | ef1eb3aa50930f026135085cd160b1212cdfe817 (patch) | |
tree | 12ed99fd9e7dc658b0e1bb0bc78e2ad0bb887dca | |
parent | 53fd7550ec40571e26f730a0d3fc0a5dd93ecda2 (diff) |
fscrypto: make filename crypto functions return 0 on success
Several filename crypto functions: fname_decrypt(),
fscrypt_fname_disk_to_usr(), and fscrypt_fname_usr_to_disk(), returned
the output length on success or -errno on failure. However, the output
length was redundant with the value written to 'oname->len'. It is also
potentially error-prone to make callers have to check for '< 0' instead
of '!= 0'.
Therefore, make these functions return 0 instead of a length, and make
the callers who cared about the return value being a length use
'oname->len' instead. For consistency also make other callers check for
a nonzero result rather than a negative result.
This change also fixes the inconsistency of fname_encrypt() actually
already returning 0 on success, not a length like the other filename
crypto functions and as documented in its function comment.
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Andreas Dilger <adilger@dilger.ca>
Acked-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | fs/crypto/fname.c | 56 | ||||
-rw-r--r-- | fs/ext4/dir.c | 5 | ||||
-rw-r--r-- | fs/ext4/namei.c | 8 | ||||
-rw-r--r-- | fs/ext4/symlink.c | 5 | ||||
-rw-r--r-- | fs/f2fs/dir.c | 6 | ||||
-rw-r--r-- | fs/f2fs/namei.c | 6 |
6 files changed, 47 insertions, 39 deletions
diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c index 6bbc3b1859e1..90697c70c23b 100644 --- a/fs/crypto/fname.c +++ b/fs/crypto/fname.c | |||
@@ -35,11 +35,11 @@ static void fname_crypt_complete(struct crypto_async_request *req, int res) | |||
35 | } | 35 | } |
36 | 36 | ||
37 | /** | 37 | /** |
38 | * fname_encrypt() - | 38 | * fname_encrypt() - encrypt a filename |
39 | * | 39 | * |
40 | * This function encrypts the input filename, and returns the length of the | 40 | * The caller must have allocated sufficient memory for the @oname string. |
41 | * ciphertext. Errors are returned as negative numbers. We trust the caller to | 41 | * |
42 | * allocate sufficient memory to oname string. | 42 | * Return: 0 on success, -errno on failure |
43 | */ | 43 | */ |
44 | static int fname_encrypt(struct inode *inode, | 44 | static int fname_encrypt(struct inode *inode, |
45 | const struct qstr *iname, struct fscrypt_str *oname) | 45 | const struct qstr *iname, struct fscrypt_str *oname) |
@@ -105,20 +105,22 @@ static int fname_encrypt(struct inode *inode, | |||
105 | } | 105 | } |
106 | kfree(alloc_buf); | 106 | kfree(alloc_buf); |
107 | skcipher_request_free(req); | 107 | skcipher_request_free(req); |
108 | if (res < 0) | 108 | if (res < 0) { |
109 | printk_ratelimited(KERN_ERR | 109 | printk_ratelimited(KERN_ERR |
110 | "%s: Error (error code %d)\n", __func__, res); | 110 | "%s: Error (error code %d)\n", __func__, res); |
111 | return res; | ||
112 | } | ||
111 | 113 | ||
112 | oname->len = ciphertext_len; | 114 | oname->len = ciphertext_len; |
113 | return res; | 115 | return 0; |
114 | } | 116 | } |
115 | 117 | ||
116 | /* | 118 | /** |
117 | * fname_decrypt() | 119 | * fname_decrypt() - decrypt a filename |
118 | * This function decrypts the input filename, and returns | 120 | * |
119 | * the length of the plaintext. | 121 | * The caller must have allocated sufficient memory for the @oname string. |
120 | * Errors are returned as negative numbers. | 122 | * |
121 | * We trust the caller to allocate sufficient memory to oname string. | 123 | * Return: 0 on success, -errno on failure |
122 | */ | 124 | */ |
123 | static int fname_decrypt(struct inode *inode, | 125 | static int fname_decrypt(struct inode *inode, |
124 | const struct fscrypt_str *iname, | 126 | const struct fscrypt_str *iname, |
@@ -168,7 +170,7 @@ static int fname_decrypt(struct inode *inode, | |||
168 | } | 170 | } |
169 | 171 | ||
170 | oname->len = strnlen(oname->name, iname->len); | 172 | oname->len = strnlen(oname->name, iname->len); |
171 | return oname->len; | 173 | return 0; |
172 | } | 174 | } |
173 | 175 | ||
174 | static const char *lookup_table = | 176 | static const char *lookup_table = |
@@ -279,6 +281,10 @@ EXPORT_SYMBOL(fscrypt_fname_free_buffer); | |||
279 | /** | 281 | /** |
280 | * fscrypt_fname_disk_to_usr() - converts a filename from disk space to user | 282 | * fscrypt_fname_disk_to_usr() - converts a filename from disk space to user |
281 | * space | 283 | * space |
284 | * | ||
285 | * The caller must have allocated sufficient memory for the @oname string. | ||
286 | * | ||
287 | * Return: 0 on success, -errno on failure | ||
282 | */ | 288 | */ |
283 | int fscrypt_fname_disk_to_usr(struct inode *inode, | 289 | int fscrypt_fname_disk_to_usr(struct inode *inode, |
284 | u32 hash, u32 minor_hash, | 290 | u32 hash, u32 minor_hash, |
@@ -287,13 +293,12 @@ int fscrypt_fname_disk_to_usr(struct inode *inode, | |||
287 | { | 293 | { |
288 | const struct qstr qname = FSTR_TO_QSTR(iname); | 294 | const struct qstr qname = FSTR_TO_QSTR(iname); |
289 | char buf[24]; | 295 | char buf[24]; |
290 | int ret; | ||
291 | 296 | ||
292 | if (fscrypt_is_dot_dotdot(&qname)) { | 297 | if (fscrypt_is_dot_dotdot(&qname)) { |
293 | oname->name[0] = '.'; | 298 | oname->name[0] = '.'; |
294 | oname->name[iname->len - 1] = '.'; | 299 | oname->name[iname->len - 1] = '.'; |
295 | oname->len = iname->len; | 300 | oname->len = iname->len; |
296 | return oname->len; | 301 | return 0; |
297 | } | 302 | } |
298 | 303 | ||
299 | if (iname->len < FS_CRYPTO_BLOCK_SIZE) | 304 | if (iname->len < FS_CRYPTO_BLOCK_SIZE) |
@@ -303,9 +308,9 @@ int fscrypt_fname_disk_to_usr(struct inode *inode, | |||
303 | return fname_decrypt(inode, iname, oname); | 308 | return fname_decrypt(inode, iname, oname); |
304 | 309 | ||
305 | if (iname->len <= FS_FNAME_CRYPTO_DIGEST_SIZE) { | 310 | if (iname->len <= FS_FNAME_CRYPTO_DIGEST_SIZE) { |
306 | ret = digest_encode(iname->name, iname->len, oname->name); | 311 | oname->len = digest_encode(iname->name, iname->len, |
307 | oname->len = ret; | 312 | oname->name); |
308 | return ret; | 313 | return 0; |
309 | } | 314 | } |
310 | if (hash) { | 315 | if (hash) { |
311 | memcpy(buf, &hash, 4); | 316 | memcpy(buf, &hash, 4); |
@@ -315,15 +320,18 @@ int fscrypt_fname_disk_to_usr(struct inode *inode, | |||
315 | } | 320 | } |
316 | memcpy(buf + 8, iname->name + iname->len - 16, 16); | 321 | memcpy(buf + 8, iname->name + iname->len - 16, 16); |
317 | oname->name[0] = '_'; | 322 | oname->name[0] = '_'; |
318 | ret = digest_encode(buf, 24, oname->name + 1); | 323 | oname->len = 1 + digest_encode(buf, 24, oname->name + 1); |
319 | oname->len = ret + 1; | 324 | return 0; |
320 | return ret + 1; | ||
321 | } | 325 | } |
322 | EXPORT_SYMBOL(fscrypt_fname_disk_to_usr); | 326 | EXPORT_SYMBOL(fscrypt_fname_disk_to_usr); |
323 | 327 | ||
324 | /** | 328 | /** |
325 | * fscrypt_fname_usr_to_disk() - converts a filename from user space to disk | 329 | * fscrypt_fname_usr_to_disk() - converts a filename from user space to disk |
326 | * space | 330 | * space |
331 | * | ||
332 | * The caller must have allocated sufficient memory for the @oname string. | ||
333 | * | ||
334 | * Return: 0 on success, -errno on failure | ||
327 | */ | 335 | */ |
328 | int fscrypt_fname_usr_to_disk(struct inode *inode, | 336 | int fscrypt_fname_usr_to_disk(struct inode *inode, |
329 | const struct qstr *iname, | 337 | const struct qstr *iname, |
@@ -333,7 +341,7 @@ int fscrypt_fname_usr_to_disk(struct inode *inode, | |||
333 | oname->name[0] = '.'; | 341 | oname->name[0] = '.'; |
334 | oname->name[iname->len - 1] = '.'; | 342 | oname->name[iname->len - 1] = '.'; |
335 | oname->len = iname->len; | 343 | oname->len = iname->len; |
336 | return oname->len; | 344 | return 0; |
337 | } | 345 | } |
338 | if (inode->i_crypt_info) | 346 | if (inode->i_crypt_info) |
339 | return fname_encrypt(inode, iname, oname); | 347 | return fname_encrypt(inode, iname, oname); |
@@ -367,10 +375,10 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname, | |||
367 | if (dir->i_crypt_info) { | 375 | if (dir->i_crypt_info) { |
368 | ret = fscrypt_fname_alloc_buffer(dir, iname->len, | 376 | ret = fscrypt_fname_alloc_buffer(dir, iname->len, |
369 | &fname->crypto_buf); | 377 | &fname->crypto_buf); |
370 | if (ret < 0) | 378 | if (ret) |
371 | return ret; | 379 | return ret; |
372 | ret = fname_encrypt(dir, iname, &fname->crypto_buf); | 380 | ret = fname_encrypt(dir, iname, &fname->crypto_buf); |
373 | if (ret < 0) | 381 | if (ret) |
374 | goto errout; | 382 | goto errout; |
375 | fname->disk_name.name = fname->crypto_buf.name; | 383 | fname->disk_name.name = fname->crypto_buf.name; |
376 | fname->disk_name.len = fname->crypto_buf.len; | 384 | fname->disk_name.len = fname->crypto_buf.len; |
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 67415e0e6af0..4d4b91029109 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c | |||
@@ -260,11 +260,12 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx) | |||
260 | /* Directory is encrypted */ | 260 | /* Directory is encrypted */ |
261 | err = fscrypt_fname_disk_to_usr(inode, | 261 | err = fscrypt_fname_disk_to_usr(inode, |
262 | 0, 0, &de_name, &fstr); | 262 | 0, 0, &de_name, &fstr); |
263 | de_name = fstr; | ||
263 | fstr.len = save_len; | 264 | fstr.len = save_len; |
264 | if (err < 0) | 265 | if (err) |
265 | goto errout; | 266 | goto errout; |
266 | if (!dir_emit(ctx, | 267 | if (!dir_emit(ctx, |
267 | fstr.name, err, | 268 | de_name.name, de_name.len, |
268 | le32_to_cpu(de->inode), | 269 | le32_to_cpu(de->inode), |
269 | get_dtype(sb, de->file_type))) | 270 | get_dtype(sb, de->file_type))) |
270 | goto done; | 271 | goto done; |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 34c0142caf6a..2243ae2ad2ee 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -639,7 +639,7 @@ static struct stats dx_show_leaf(struct inode *dir, | |||
639 | res = fscrypt_fname_alloc_buffer( | 639 | res = fscrypt_fname_alloc_buffer( |
640 | dir, len, | 640 | dir, len, |
641 | &fname_crypto_str); | 641 | &fname_crypto_str); |
642 | if (res < 0) | 642 | if (res) |
643 | printk(KERN_WARNING "Error " | 643 | printk(KERN_WARNING "Error " |
644 | "allocating crypto " | 644 | "allocating crypto " |
645 | "buffer--skipping " | 645 | "buffer--skipping " |
@@ -647,7 +647,7 @@ static struct stats dx_show_leaf(struct inode *dir, | |||
647 | res = fscrypt_fname_disk_to_usr(dir, | 647 | res = fscrypt_fname_disk_to_usr(dir, |
648 | 0, 0, &de_name, | 648 | 0, 0, &de_name, |
649 | &fname_crypto_str); | 649 | &fname_crypto_str); |
650 | if (res < 0) { | 650 | if (res) { |
651 | printk(KERN_WARNING "Error " | 651 | printk(KERN_WARNING "Error " |
652 | "converting filename " | 652 | "converting filename " |
653 | "from disk to usr" | 653 | "from disk to usr" |
@@ -1011,7 +1011,7 @@ static int htree_dirblock_to_tree(struct file *dir_file, | |||
1011 | err = fscrypt_fname_disk_to_usr(dir, hinfo->hash, | 1011 | err = fscrypt_fname_disk_to_usr(dir, hinfo->hash, |
1012 | hinfo->minor_hash, &de_name, | 1012 | hinfo->minor_hash, &de_name, |
1013 | &fname_crypto_str); | 1013 | &fname_crypto_str); |
1014 | if (err < 0) { | 1014 | if (err) { |
1015 | count = err; | 1015 | count = err; |
1016 | goto errout; | 1016 | goto errout; |
1017 | } | 1017 | } |
@@ -3144,7 +3144,7 @@ static int ext4_symlink(struct inode *dir, | |||
3144 | istr.name = (const unsigned char *) symname; | 3144 | istr.name = (const unsigned char *) symname; |
3145 | istr.len = len; | 3145 | istr.len = len; |
3146 | err = fscrypt_fname_usr_to_disk(inode, &istr, &ostr); | 3146 | err = fscrypt_fname_usr_to_disk(inode, &istr, &ostr); |
3147 | if (err < 0) | 3147 | if (err) |
3148 | goto err_drop_inode; | 3148 | goto err_drop_inode; |
3149 | sd->len = cpu_to_le16(ostr.len); | 3149 | sd->len = cpu_to_le16(ostr.len); |
3150 | disk_link.name = (char *) sd; | 3150 | disk_link.name = (char *) sd; |
diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c index 04a7850a0d45..0a26cbd529c8 100644 --- a/fs/ext4/symlink.c +++ b/fs/ext4/symlink.c | |||
@@ -68,12 +68,11 @@ static const char *ext4_encrypted_get_link(struct dentry *dentry, | |||
68 | paddr = pstr.name; | 68 | paddr = pstr.name; |
69 | 69 | ||
70 | res = fscrypt_fname_disk_to_usr(inode, 0, 0, &cstr, &pstr); | 70 | res = fscrypt_fname_disk_to_usr(inode, 0, 0, &cstr, &pstr); |
71 | if (res < 0) | 71 | if (res) |
72 | goto errout; | 72 | goto errout; |
73 | 73 | ||
74 | /* Null-terminate the name */ | 74 | /* Null-terminate the name */ |
75 | if (res <= pstr.len) | 75 | paddr[pstr.len] = '\0'; |
76 | paddr[res] = '\0'; | ||
77 | if (cpage) | 76 | if (cpage) |
78 | put_page(cpage); | 77 | put_page(cpage); |
79 | set_delayed_call(done, kfree_link, paddr); | 78 | set_delayed_call(done, kfree_link, paddr); |
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 9054aeac8015..8716943335b1 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c | |||
@@ -786,7 +786,7 @@ bool f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, | |||
786 | 786 | ||
787 | if (f2fs_encrypted_inode(d->inode)) { | 787 | if (f2fs_encrypted_inode(d->inode)) { |
788 | int save_len = fstr->len; | 788 | int save_len = fstr->len; |
789 | int ret; | 789 | int err; |
790 | 790 | ||
791 | de_name.name = f2fs_kmalloc(de_name.len, GFP_NOFS); | 791 | de_name.name = f2fs_kmalloc(de_name.len, GFP_NOFS); |
792 | if (!de_name.name) | 792 | if (!de_name.name) |
@@ -794,11 +794,11 @@ bool f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, | |||
794 | 794 | ||
795 | memcpy(de_name.name, d->filename[bit_pos], de_name.len); | 795 | memcpy(de_name.name, d->filename[bit_pos], de_name.len); |
796 | 796 | ||
797 | ret = fscrypt_fname_disk_to_usr(d->inode, | 797 | err = fscrypt_fname_disk_to_usr(d->inode, |
798 | (u32)de->hash_code, 0, | 798 | (u32)de->hash_code, 0, |
799 | &de_name, fstr); | 799 | &de_name, fstr); |
800 | kfree(de_name.name); | 800 | kfree(de_name.name); |
801 | if (ret < 0) | 801 | if (err) |
802 | return true; | 802 | return true; |
803 | 803 | ||
804 | de_name = *fstr; | 804 | de_name = *fstr; |
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 73fa356f8fbb..afd56332d34c 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c | |||
@@ -449,7 +449,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, | |||
449 | ostr.name = sd->encrypted_path; | 449 | ostr.name = sd->encrypted_path; |
450 | ostr.len = disk_link.len; | 450 | ostr.len = disk_link.len; |
451 | err = fscrypt_fname_usr_to_disk(inode, &istr, &ostr); | 451 | err = fscrypt_fname_usr_to_disk(inode, &istr, &ostr); |
452 | if (err < 0) | 452 | if (err) |
453 | goto err_out; | 453 | goto err_out; |
454 | 454 | ||
455 | sd->len = cpu_to_le16(ostr.len); | 455 | sd->len = cpu_to_le16(ostr.len); |
@@ -1048,7 +1048,7 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry, | |||
1048 | goto errout; | 1048 | goto errout; |
1049 | 1049 | ||
1050 | res = fscrypt_fname_disk_to_usr(inode, 0, 0, &cstr, &pstr); | 1050 | res = fscrypt_fname_disk_to_usr(inode, 0, 0, &cstr, &pstr); |
1051 | if (res < 0) | 1051 | if (res) |
1052 | goto errout; | 1052 | goto errout; |
1053 | 1053 | ||
1054 | /* this is broken symlink case */ | 1054 | /* this is broken symlink case */ |
@@ -1060,7 +1060,7 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry, | |||
1060 | paddr = pstr.name; | 1060 | paddr = pstr.name; |
1061 | 1061 | ||
1062 | /* Null-terminate the name */ | 1062 | /* Null-terminate the name */ |
1063 | paddr[res] = '\0'; | 1063 | paddr[pstr.len] = '\0'; |
1064 | 1064 | ||
1065 | put_page(cpage); | 1065 | put_page(cpage); |
1066 | set_delayed_call(done, kfree_link, paddr); | 1066 | set_delayed_call(done, kfree_link, paddr); |