e2fsck: check for encrypted directory entries with too-short file names

If there are directory entries with file names which are less than 16
bytes, it turns out that passing less than the crypto block size to
the kernel's crypto layer will cause the kernel to crash.

However, since there never should be encrypted directory entries where
the file name is less than 16 bytes (the AES block size), change
e2fsck to offer to address this corruption by deleting the directory
entry.

(We need to checks for this condition into the kernel as well.)

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
debian
Theodore Ts'o 2015-07-16 17:19:38 -04:00
parent 4ecd63d786
commit e3dd5c6f1a
8 changed files with 54 additions and 0 deletions

View File

@ -494,6 +494,20 @@ static int check_name(e2fsck_t ctx,
return ret;
}
static int encrypted_check_name(e2fsck_t ctx,
struct ext2_dir_entry *dirent,
struct problem_context *pctx)
{
if (ext2fs_dirent_name_len(dirent) < EXT4_CRYPTO_BLOCK_SIZE) {
if (fix_problem(ctx, PR_2_BAD_ENCRYPTED_NAME, pctx)) {
dirent->inode = 0;
return 1;
}
ext2fs_unmark_valid(ctx->fs);
}
return 0;
}
/*
* Check the directory filetype (if present)
*/
@ -1383,6 +1397,12 @@ skip_checksum:
if (!encrypted && check_name(ctx, dirent, &cd->pctx))
dir_modified++;
if (encrypted && (dot_state) > 1 &&
encrypted_check_name(ctx, dirent, &cd->pctx)) {
dir_modified++;
goto next;
}
if (check_filetype(ctx, dirent, ino, &cd->pctx))
dir_modified++;

View File

@ -1613,6 +1613,11 @@ static struct e2fsck_problem problem_table[] = {
N_("Fixing size of inline @d @i %i failed.\n"),
PROMPT_TRUNCATE, 0 },
/* Encrypted directory entry is too short */
{ PR_2_BAD_ENCRYPTED_NAME,
N_("Encrypted @E is too short.\n"),
PROMPT_CLEAR, 0 },
/* Pass 3 errors */
/* Pass 3: Checking directory connectivity */

View File

@ -963,6 +963,9 @@ struct problem_context {
/* fixing inline dir size failed */
#define PR_2_FIX_INLINE_DIR_FAILED 0x02004F
/* Encrypted directory entry is too short */
#define PR_2_BAD_ENCRYPTED_NAME 0x020050
/*
* Pass 3 errors
*/

View File

@ -579,6 +579,7 @@ struct ext2_inode_large {
#define EXT4_MAX_KEY_SIZE 64
#define EXT4_KEY_DESCRIPTOR_SIZE 8
#define EXT4_CRYPTO_BLOCK_SIZE 16
/* Password derivation constants */
#define EXT4_MAX_PASSPHRASE_SIZE 1024

View File

@ -0,0 +1,17 @@
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Encrypted entry 'motd' in /get_shorty (12) is too short.
Clear? yes
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Unattached inode 13
Connect to /lost+found? yes
Inode 13 ref count is 2, should be 1. Fix? yes
Pass 5: Checking group summary information
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 13/16 files (0.0% non-contiguous), 23/100 blocks
Exit status is 1

View File

@ -0,0 +1,7 @@
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: 13/16 files (0.0% non-contiguous), 23/100 blocks
Exit status is 0

Binary file not shown.

View File

@ -0,0 +1 @@
short encrypted directory entry