aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/crypto/fname.c1
-rw-r--r--fs/crypto/hooks.c11
-rw-r--r--fs/ext4/ext4.h62
-rw-r--r--fs/ext4/namei.c76
-rw-r--r--fs/f2fs/namei.c17
-rw-r--r--fs/ubifs/dir.c8
-rw-r--r--include/linux/fscrypt.h30
7 files changed, 139 insertions, 66 deletions
diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
index 050384c79f40..eccea3d8f923 100644
--- a/fs/crypto/fname.c
+++ b/fs/crypto/fname.c
@@ -356,6 +356,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
356 } 356 }
357 if (!lookup) 357 if (!lookup)
358 return -ENOKEY; 358 return -ENOKEY;
359 fname->is_ciphertext_name = true;
359 360
360 /* 361 /*
361 * We don't have the key and we are doing a lookup; decode the 362 * We don't have the key and we are doing a lookup; decode the
diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c
index 9d8910e86ee5..042d5b44f4ed 100644
--- a/fs/crypto/hooks.c
+++ b/fs/crypto/hooks.c
@@ -104,20 +104,21 @@ int __fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry,
104} 104}
105EXPORT_SYMBOL_GPL(__fscrypt_prepare_rename); 105EXPORT_SYMBOL_GPL(__fscrypt_prepare_rename);
106 106
107int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry) 107int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry,
108 struct fscrypt_name *fname)
108{ 109{
109 int err = fscrypt_get_encryption_info(dir); 110 int err = fscrypt_setup_filename(dir, &dentry->d_name, 1, fname);
110 111
111 if (err) 112 if (err && err != -ENOENT)
112 return err; 113 return err;
113 114
114 if (!fscrypt_has_encryption_key(dir)) { 115 if (fname->is_ciphertext_name) {
115 spin_lock(&dentry->d_lock); 116 spin_lock(&dentry->d_lock);
116 dentry->d_flags |= DCACHE_ENCRYPTED_NAME; 117 dentry->d_flags |= DCACHE_ENCRYPTED_NAME;
117 spin_unlock(&dentry->d_lock); 118 spin_unlock(&dentry->d_lock);
118 d_set_d_op(dentry, &fscrypt_d_ops); 119 d_set_d_op(dentry, &fscrypt_d_ops);
119 } 120 }
120 return 0; 121 return err;
121} 122}
122EXPORT_SYMBOL_GPL(__fscrypt_prepare_lookup); 123EXPORT_SYMBOL_GPL(__fscrypt_prepare_lookup);
123 124
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 82ffdacdc7fa..e64a4ee96d30 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2287,23 +2287,47 @@ extern unsigned ext4_free_clusters_after_init(struct super_block *sb,
2287ext4_fsblk_t ext4_inode_to_goal_block(struct inode *); 2287ext4_fsblk_t ext4_inode_to_goal_block(struct inode *);
2288 2288
2289#ifdef CONFIG_FS_ENCRYPTION 2289#ifdef CONFIG_FS_ENCRYPTION
2290static inline void ext4_fname_from_fscrypt_name(struct ext4_filename *dst,
2291 const struct fscrypt_name *src)
2292{
2293 memset(dst, 0, sizeof(*dst));
2294
2295 dst->usr_fname = src->usr_fname;
2296 dst->disk_name = src->disk_name;
2297 dst->hinfo.hash = src->hash;
2298 dst->hinfo.minor_hash = src->minor_hash;
2299 dst->crypto_buf = src->crypto_buf;
2300}
2301
2290static inline int ext4_fname_setup_filename(struct inode *dir, 2302static inline int ext4_fname_setup_filename(struct inode *dir,
2291 const struct qstr *iname, 2303 const struct qstr *iname,
2292 int lookup, struct ext4_filename *fname) 2304 int lookup,
2305 struct ext4_filename *fname)
2293{ 2306{
2294 struct fscrypt_name name; 2307 struct fscrypt_name name;
2295 int err; 2308 int err;
2296 2309
2297 memset(fname, 0, sizeof(struct ext4_filename));
2298
2299 err = fscrypt_setup_filename(dir, iname, lookup, &name); 2310 err = fscrypt_setup_filename(dir, iname, lookup, &name);
2311 if (err)
2312 return err;
2300 2313
2301 fname->usr_fname = name.usr_fname; 2314 ext4_fname_from_fscrypt_name(fname, &name);
2302 fname->disk_name = name.disk_name; 2315 return 0;
2303 fname->hinfo.hash = name.hash; 2316}
2304 fname->hinfo.minor_hash = name.minor_hash; 2317
2305 fname->crypto_buf = name.crypto_buf; 2318static inline int ext4_fname_prepare_lookup(struct inode *dir,
2306 return err; 2319 struct dentry *dentry,
2320 struct ext4_filename *fname)
2321{
2322 struct fscrypt_name name;
2323 int err;
2324
2325 err = fscrypt_prepare_lookup(dir, dentry, &name);
2326 if (err)
2327 return err;
2328
2329 ext4_fname_from_fscrypt_name(fname, &name);
2330 return 0;
2307} 2331}
2308 2332
2309static inline void ext4_fname_free_filename(struct ext4_filename *fname) 2333static inline void ext4_fname_free_filename(struct ext4_filename *fname)
@@ -2317,19 +2341,27 @@ static inline void ext4_fname_free_filename(struct ext4_filename *fname)
2317 fname->usr_fname = NULL; 2341 fname->usr_fname = NULL;
2318 fname->disk_name.name = NULL; 2342 fname->disk_name.name = NULL;
2319} 2343}
2320#else 2344#else /* !CONFIG_FS_ENCRYPTION */
2321static inline int ext4_fname_setup_filename(struct inode *dir, 2345static inline int ext4_fname_setup_filename(struct inode *dir,
2322 const struct qstr *iname, 2346 const struct qstr *iname,
2323 int lookup, struct ext4_filename *fname) 2347 int lookup,
2348 struct ext4_filename *fname)
2324{ 2349{
2325 fname->usr_fname = iname; 2350 fname->usr_fname = iname;
2326 fname->disk_name.name = (unsigned char *) iname->name; 2351 fname->disk_name.name = (unsigned char *) iname->name;
2327 fname->disk_name.len = iname->len; 2352 fname->disk_name.len = iname->len;
2328 return 0; 2353 return 0;
2329} 2354}
2330static inline void ext4_fname_free_filename(struct ext4_filename *fname) { }
2331 2355
2332#endif 2356static inline int ext4_fname_prepare_lookup(struct inode *dir,
2357 struct dentry *dentry,
2358 struct ext4_filename *fname)
2359{
2360 return ext4_fname_setup_filename(dir, &dentry->d_name, 1, fname);
2361}
2362
2363static inline void ext4_fname_free_filename(struct ext4_filename *fname) { }
2364#endif /* !CONFIG_FS_ENCRYPTION */
2333 2365
2334/* dir.c */ 2366/* dir.c */
2335extern int __ext4_check_dir_entry(const char *, unsigned int, struct inode *, 2367extern int __ext4_check_dir_entry(const char *, unsigned int, struct inode *,
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 980166a8122a..3ba6f30db8d9 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1327,7 +1327,7 @@ static int is_dx_internal_node(struct inode *dir, ext4_lblk_t block,
1327} 1327}
1328 1328
1329/* 1329/*
1330 * ext4_find_entry() 1330 * __ext4_find_entry()
1331 * 1331 *
1332 * finds an entry in the specified directory with the wanted name. It 1332 * finds an entry in the specified directory with the wanted name. It
1333 * returns the cache buffer in which the entry was found, and the entry 1333 * returns the cache buffer in which the entry was found, and the entry
@@ -1337,39 +1337,32 @@ static int is_dx_internal_node(struct inode *dir, ext4_lblk_t block,
1337 * The returned buffer_head has ->b_count elevated. The caller is expected 1337 * The returned buffer_head has ->b_count elevated. The caller is expected
1338 * to brelse() it when appropriate. 1338 * to brelse() it when appropriate.
1339 */ 1339 */
1340static struct buffer_head * ext4_find_entry (struct inode *dir, 1340static struct buffer_head *__ext4_find_entry(struct inode *dir,
1341 const struct qstr *d_name, 1341 struct ext4_filename *fname,
1342 struct ext4_dir_entry_2 **res_dir, 1342 struct ext4_dir_entry_2 **res_dir,
1343 int *inlined) 1343 int *inlined)
1344{ 1344{
1345 struct super_block *sb; 1345 struct super_block *sb;
1346 struct buffer_head *bh_use[NAMEI_RA_SIZE]; 1346 struct buffer_head *bh_use[NAMEI_RA_SIZE];
1347 struct buffer_head *bh, *ret = NULL; 1347 struct buffer_head *bh, *ret = NULL;
1348 ext4_lblk_t start, block; 1348 ext4_lblk_t start, block;
1349 const u8 *name = d_name->name; 1349 const u8 *name = fname->usr_fname->name;
1350 size_t ra_max = 0; /* Number of bh's in the readahead 1350 size_t ra_max = 0; /* Number of bh's in the readahead
1351 buffer, bh_use[] */ 1351 buffer, bh_use[] */
1352 size_t ra_ptr = 0; /* Current index into readahead 1352 size_t ra_ptr = 0; /* Current index into readahead
1353 buffer */ 1353 buffer */
1354 ext4_lblk_t nblocks; 1354 ext4_lblk_t nblocks;
1355 int i, namelen, retval; 1355 int i, namelen, retval;
1356 struct ext4_filename fname;
1357 1356
1358 *res_dir = NULL; 1357 *res_dir = NULL;
1359 sb = dir->i_sb; 1358 sb = dir->i_sb;
1360 namelen = d_name->len; 1359 namelen = fname->usr_fname->len;
1361 if (namelen > EXT4_NAME_LEN) 1360 if (namelen > EXT4_NAME_LEN)
1362 return NULL; 1361 return NULL;
1363 1362
1364 retval = ext4_fname_setup_filename(dir, d_name, 1, &fname);
1365 if (retval == -ENOENT)
1366 return NULL;
1367 if (retval)
1368 return ERR_PTR(retval);
1369
1370 if (ext4_has_inline_data(dir)) { 1363 if (ext4_has_inline_data(dir)) {
1371 int has_inline_data = 1; 1364 int has_inline_data = 1;
1372 ret = ext4_find_inline_entry(dir, &fname, res_dir, 1365 ret = ext4_find_inline_entry(dir, fname, res_dir,
1373 &has_inline_data); 1366 &has_inline_data);
1374 if (has_inline_data) { 1367 if (has_inline_data) {
1375 if (inlined) 1368 if (inlined)
@@ -1389,7 +1382,7 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
1389 goto restart; 1382 goto restart;
1390 } 1383 }
1391 if (is_dx(dir)) { 1384 if (is_dx(dir)) {
1392 ret = ext4_dx_find_entry(dir, &fname, res_dir); 1385 ret = ext4_dx_find_entry(dir, fname, res_dir);
1393 /* 1386 /*
1394 * On success, or if the error was file not found, 1387 * On success, or if the error was file not found,
1395 * return. Otherwise, fall back to doing a search the 1388 * return. Otherwise, fall back to doing a search the
@@ -1453,7 +1446,7 @@ restart:
1453 goto cleanup_and_exit; 1446 goto cleanup_and_exit;
1454 } 1447 }
1455 set_buffer_verified(bh); 1448 set_buffer_verified(bh);
1456 i = search_dirblock(bh, dir, &fname, 1449 i = search_dirblock(bh, dir, fname,
1457 block << EXT4_BLOCK_SIZE_BITS(sb), res_dir); 1450 block << EXT4_BLOCK_SIZE_BITS(sb), res_dir);
1458 if (i == 1) { 1451 if (i == 1) {
1459 EXT4_I(dir)->i_dir_start_lookup = block; 1452 EXT4_I(dir)->i_dir_start_lookup = block;
@@ -1484,10 +1477,50 @@ cleanup_and_exit:
1484 /* Clean up the read-ahead blocks */ 1477 /* Clean up the read-ahead blocks */
1485 for (; ra_ptr < ra_max; ra_ptr++) 1478 for (; ra_ptr < ra_max; ra_ptr++)
1486 brelse(bh_use[ra_ptr]); 1479 brelse(bh_use[ra_ptr]);
1487 ext4_fname_free_filename(&fname);
1488 return ret; 1480 return ret;
1489} 1481}
1490 1482
1483static struct buffer_head *ext4_find_entry(struct inode *dir,
1484 const struct qstr *d_name,
1485 struct ext4_dir_entry_2 **res_dir,
1486 int *inlined)
1487{
1488 int err;
1489 struct ext4_filename fname;
1490 struct buffer_head *bh;
1491
1492 err = ext4_fname_setup_filename(dir, d_name, 1, &fname);
1493 if (err == -ENOENT)
1494 return NULL;
1495 if (err)
1496 return ERR_PTR(err);
1497
1498 bh = __ext4_find_entry(dir, &fname, res_dir, inlined);
1499
1500 ext4_fname_free_filename(&fname);
1501 return bh;
1502}
1503
1504static struct buffer_head *ext4_lookup_entry(struct inode *dir,
1505 struct dentry *dentry,
1506 struct ext4_dir_entry_2 **res_dir)
1507{
1508 int err;
1509 struct ext4_filename fname;
1510 struct buffer_head *bh;
1511
1512 err = ext4_fname_prepare_lookup(dir, dentry, &fname);
1513 if (err == -ENOENT)
1514 return NULL;
1515 if (err)
1516 return ERR_PTR(err);
1517
1518 bh = __ext4_find_entry(dir, &fname, res_dir, NULL);
1519
1520 ext4_fname_free_filename(&fname);
1521 return bh;
1522}
1523
1491static struct buffer_head * ext4_dx_find_entry(struct inode *dir, 1524static struct buffer_head * ext4_dx_find_entry(struct inode *dir,
1492 struct ext4_filename *fname, 1525 struct ext4_filename *fname,
1493 struct ext4_dir_entry_2 **res_dir) 1526 struct ext4_dir_entry_2 **res_dir)
@@ -1546,16 +1579,11 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
1546 struct inode *inode; 1579 struct inode *inode;
1547 struct ext4_dir_entry_2 *de; 1580 struct ext4_dir_entry_2 *de;
1548 struct buffer_head *bh; 1581 struct buffer_head *bh;
1549 int err;
1550
1551 err = fscrypt_prepare_lookup(dir, dentry, flags);
1552 if (err)
1553 return ERR_PTR(err);
1554 1582
1555 if (dentry->d_name.len > EXT4_NAME_LEN) 1583 if (dentry->d_name.len > EXT4_NAME_LEN)
1556 return ERR_PTR(-ENAMETOOLONG); 1584 return ERR_PTR(-ENAMETOOLONG);
1557 1585
1558 bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL); 1586 bh = ext4_lookup_entry(dir, dentry, &de);
1559 if (IS_ERR(bh)) 1587 if (IS_ERR(bh))
1560 return ERR_CAST(bh); 1588 return ERR_CAST(bh);
1561 inode = NULL; 1589 inode = NULL;
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index f5e34e467003..c3e8a901d47a 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -436,19 +436,23 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
436 nid_t ino = -1; 436 nid_t ino = -1;
437 int err = 0; 437 int err = 0;
438 unsigned int root_ino = F2FS_ROOT_INO(F2FS_I_SB(dir)); 438 unsigned int root_ino = F2FS_ROOT_INO(F2FS_I_SB(dir));
439 struct fscrypt_name fname;
439 440
440 trace_f2fs_lookup_start(dir, dentry, flags); 441 trace_f2fs_lookup_start(dir, dentry, flags);
441 442
442 err = fscrypt_prepare_lookup(dir, dentry, flags);
443 if (err)
444 goto out;
445
446 if (dentry->d_name.len > F2FS_NAME_LEN) { 443 if (dentry->d_name.len > F2FS_NAME_LEN) {
447 err = -ENAMETOOLONG; 444 err = -ENAMETOOLONG;
448 goto out; 445 goto out;
449 } 446 }
450 447
451 de = f2fs_find_entry(dir, &dentry->d_name, &page); 448 err = fscrypt_prepare_lookup(dir, dentry, &fname);
449 if (err == -ENOENT)
450 goto out_splice;
451 if (err)
452 goto out;
453 de = __f2fs_find_entry(dir, &fname, &page);
454 fscrypt_free_filename(&fname);
455
452 if (!de) { 456 if (!de) {
453 if (IS_ERR(page)) { 457 if (IS_ERR(page)) {
454 err = PTR_ERR(page); 458 err = PTR_ERR(page);
@@ -488,8 +492,7 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
488 } 492 }
489out_splice: 493out_splice:
490 new = d_splice_alias(inode, dentry); 494 new = d_splice_alias(inode, dentry);
491 if (IS_ERR(new)) 495 err = PTR_ERR_OR_ZERO(new);
492 err = PTR_ERR(new);
493 trace_f2fs_lookup_end(dir, dentry, ino, err); 496 trace_f2fs_lookup_end(dir, dentry, ino, err);
494 return new; 497 return new;
495out_iput: 498out_iput:
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 5767b373a8ff..b73de6d04fa3 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -220,11 +220,9 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
220 220
221 dbg_gen("'%pd' in dir ino %lu", dentry, dir->i_ino); 221 dbg_gen("'%pd' in dir ino %lu", dentry, dir->i_ino);
222 222
223 err = fscrypt_prepare_lookup(dir, dentry, flags); 223 err = fscrypt_prepare_lookup(dir, dentry, &nm);
224 if (err) 224 if (err == -ENOENT)
225 return ERR_PTR(err); 225 return d_splice_alias(NULL, dentry);
226
227 err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm);
228 if (err) 226 if (err)
229 return ERR_PTR(err); 227 return ERR_PTR(err);
230 228
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index 76c518f1e4c7..abe7081b6b22 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -33,6 +33,7 @@ struct fscrypt_name {
33 u32 hash; 33 u32 hash;
34 u32 minor_hash; 34 u32 minor_hash;
35 struct fscrypt_str crypto_buf; 35 struct fscrypt_str crypto_buf;
36 bool is_ciphertext_name;
36}; 37};
37 38
38#define FSTR_INIT(n, l) { .name = n, .len = l } 39#define FSTR_INIT(n, l) { .name = n, .len = l }
@@ -234,7 +235,8 @@ extern int __fscrypt_prepare_rename(struct inode *old_dir,
234 struct inode *new_dir, 235 struct inode *new_dir,
235 struct dentry *new_dentry, 236 struct dentry *new_dentry,
236 unsigned int flags); 237 unsigned int flags);
237extern int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry); 238extern int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry,
239 struct fscrypt_name *fname);
238extern int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len, 240extern int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
239 unsigned int max_len, 241 unsigned int max_len,
240 struct fscrypt_str *disk_link); 242 struct fscrypt_str *disk_link);
@@ -347,7 +349,7 @@ static inline int fscrypt_setup_filename(struct inode *dir,
347 if (IS_ENCRYPTED(dir)) 349 if (IS_ENCRYPTED(dir))
348 return -EOPNOTSUPP; 350 return -EOPNOTSUPP;
349 351
350 memset(fname, 0, sizeof(struct fscrypt_name)); 352 memset(fname, 0, sizeof(*fname));
351 fname->usr_fname = iname; 353 fname->usr_fname = iname;
352 fname->disk_name.name = (unsigned char *)iname->name; 354 fname->disk_name.name = (unsigned char *)iname->name;
353 fname->disk_name.len = iname->len; 355 fname->disk_name.len = iname->len;
@@ -434,7 +436,8 @@ static inline int __fscrypt_prepare_rename(struct inode *old_dir,
434} 436}
435 437
436static inline int __fscrypt_prepare_lookup(struct inode *dir, 438static inline int __fscrypt_prepare_lookup(struct inode *dir,
437 struct dentry *dentry) 439 struct dentry *dentry,
440 struct fscrypt_name *fname)
438{ 441{
439 return -EOPNOTSUPP; 442 return -EOPNOTSUPP;
440} 443}
@@ -555,25 +558,32 @@ static inline int fscrypt_prepare_rename(struct inode *old_dir,
555 * fscrypt_prepare_lookup - prepare to lookup a name in a possibly-encrypted directory 558 * fscrypt_prepare_lookup - prepare to lookup a name in a possibly-encrypted directory
556 * @dir: directory being searched 559 * @dir: directory being searched
557 * @dentry: filename being looked up 560 * @dentry: filename being looked up
558 * @flags: lookup flags 561 * @fname: (output) the name to use to search the on-disk directory
559 * 562 *
560 * Prepare for ->lookup() in a directory which may be encrypted. Lookups can be 563 * Prepare for ->lookup() in a directory which may be encrypted by determining
561 * done with or without the directory's encryption key; without the key, 564 * the name that will actually be used to search the directory on-disk. Lookups
565 * can be done with or without the directory's encryption key; without the key,
562 * filenames are presented in encrypted form. Therefore, we'll try to set up 566 * filenames are presented in encrypted form. Therefore, we'll try to set up
563 * the directory's encryption key, but even without it the lookup can continue. 567 * the directory's encryption key, but even without it the lookup can continue.
564 * 568 *
565 * This also installs a custom ->d_revalidate() method which will invalidate the 569 * This also installs a custom ->d_revalidate() method which will invalidate the
566 * dentry if it was created without the key and the key is later added. 570 * dentry if it was created without the key and the key is later added.
567 * 571 *
568 * Return: 0 on success, -errno if a problem occurred while setting up the 572 * Return: 0 on success; -ENOENT if key is unavailable but the filename isn't a
569 * encryption key 573 * correctly formed encoded ciphertext name, so a negative dentry should be
574 * created; or another -errno code.
570 */ 575 */
571static inline int fscrypt_prepare_lookup(struct inode *dir, 576static inline int fscrypt_prepare_lookup(struct inode *dir,
572 struct dentry *dentry, 577 struct dentry *dentry,
573 unsigned int flags) 578 struct fscrypt_name *fname)
574{ 579{
575 if (IS_ENCRYPTED(dir)) 580 if (IS_ENCRYPTED(dir))
576 return __fscrypt_prepare_lookup(dir, dentry); 581 return __fscrypt_prepare_lookup(dir, dentry, fname);
582
583 memset(fname, 0, sizeof(*fname));
584 fname->usr_fname = &dentry->d_name;
585 fname->disk_name.name = (unsigned char *)dentry->d_name.name;
586 fname->disk_name.len = dentry->d_name.len;
577 return 0; 587 return 0;
578} 588}
579 589