@@ -1390,58 +1390,6 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, ext4_lblk_t block)
13901390}
13911391
13921392#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-
14451393int ext4_fname_setup_ci_filename (struct inode * dir , const struct qstr * iname ,
14461394 struct ext4_filename * name )
14471395{
@@ -1503,20 +1451,29 @@ static bool ext4_match(struct inode *parent,
15031451#if IS_ENABLED (CONFIG_UNICODE )
15041452 if (IS_CASEFOLDED (parent ) &&
15051453 (!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+ */
15111473
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 ;
15201477 }
15211478#endif
15221479
0 commit comments