@@ -1390,58 +1390,6 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, ext4_lblk_t block)
1390
1390
}
1391
1391
1392
1392
#if IS_ENABLED (CONFIG_UNICODE )
1393
- /*
1394
- * Test whether a case-insensitive directory entry matches the filename
1395
- * being searched for. If quick is set, assume the name being looked up
1396
- * is already in the casefolded form.
1397
- *
1398
- * Returns: 0 if the directory entry matches, more than 0 if it
1399
- * doesn't match or less than zero on error.
1400
- */
1401
- static int ext4_ci_compare (const struct inode * parent , const struct qstr * name ,
1402
- u8 * de_name , size_t de_name_len , bool quick )
1403
- {
1404
- const struct super_block * sb = parent -> i_sb ;
1405
- const struct unicode_map * um = sb -> s_encoding ;
1406
- struct fscrypt_str decrypted_name = FSTR_INIT (NULL , de_name_len );
1407
- struct qstr entry = QSTR_INIT (de_name , de_name_len );
1408
- int ret ;
1409
-
1410
- if (IS_ENCRYPTED (parent )) {
1411
- const struct fscrypt_str encrypted_name =
1412
- FSTR_INIT (de_name , de_name_len );
1413
-
1414
- decrypted_name .name = kmalloc (de_name_len , GFP_KERNEL );
1415
- if (!decrypted_name .name )
1416
- return - ENOMEM ;
1417
- ret = fscrypt_fname_disk_to_usr (parent , 0 , 0 , & encrypted_name ,
1418
- & decrypted_name );
1419
- if (ret < 0 )
1420
- goto out ;
1421
- entry .name = decrypted_name .name ;
1422
- entry .len = decrypted_name .len ;
1423
- }
1424
-
1425
- if (quick )
1426
- ret = utf8_strncasecmp_folded (um , name , & entry );
1427
- else
1428
- ret = utf8_strncasecmp (um , name , & entry );
1429
- if (ret < 0 ) {
1430
- /* Handle invalid character sequence as either an error
1431
- * or as an opaque byte sequence.
1432
- */
1433
- if (sb_has_strict_encoding (sb ))
1434
- ret = - EINVAL ;
1435
- else if (name -> len != entry .len )
1436
- ret = 1 ;
1437
- else
1438
- ret = !!memcmp (name -> name , entry .name , entry .len );
1439
- }
1440
- out :
1441
- kfree (decrypted_name .name );
1442
- return ret ;
1443
- }
1444
-
1445
1393
int ext4_fname_setup_ci_filename (struct inode * dir , const struct qstr * iname ,
1446
1394
struct ext4_filename * name )
1447
1395
{
@@ -1503,20 +1451,29 @@ static bool ext4_match(struct inode *parent,
1503
1451
#if IS_ENABLED (CONFIG_UNICODE )
1504
1452
if (IS_CASEFOLDED (parent ) &&
1505
1453
(!IS_ENCRYPTED (parent ) || fscrypt_has_encryption_key (parent ))) {
1506
- if (fname -> cf_name .name ) {
1507
- if (IS_ENCRYPTED (parent )) {
1508
- if (fname -> hinfo .hash != EXT4_DIRENT_HASH (de ) ||
1509
- fname -> hinfo .minor_hash !=
1510
- EXT4_DIRENT_MINOR_HASH (de )) {
1454
+ /*
1455
+ * Just checking IS_ENCRYPTED(parent) below is not
1456
+ * sufficient to decide whether one can use the hash for
1457
+ * skipping the string comparison, because the key might
1458
+ * have been added right after
1459
+ * ext4_fname_setup_ci_filename(). In this case, a hash
1460
+ * mismatch will be a false negative. Therefore, make
1461
+ * sure cf_name was properly initialized before
1462
+ * considering the calculated hash.
1463
+ */
1464
+ if (IS_ENCRYPTED (parent ) && fname -> cf_name .name &&
1465
+ (fname -> hinfo .hash != EXT4_DIRENT_HASH (de ) ||
1466
+ fname -> hinfo .minor_hash != EXT4_DIRENT_MINOR_HASH (de )))
1467
+ return false;
1468
+ /*
1469
+ * Treat comparison errors as not a match. The
1470
+ * only case where it happens is on a disk
1471
+ * corruption or ENOMEM.
1472
+ */
1511
1473
1512
- return false;
1513
- }
1514
- }
1515
- return !ext4_ci_compare (parent , & fname -> cf_name ,
1516
- de -> name , de -> name_len , true);
1517
- }
1518
- return !ext4_ci_compare (parent , fname -> usr_fname , de -> name ,
1519
- de -> name_len , false);
1474
+ return generic_ci_match (parent , fname -> usr_fname ,
1475
+ & fname -> cf_name , de -> name ,
1476
+ de -> name_len ) > 0 ;
1520
1477
}
1521
1478
#endif
1522
1479
0 commit comments