diff options
author | Eric Biggers <ebiggers@google.com> | 2018-03-02 16:59:18 -0800 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2018-03-03 16:39:59 -0500 |
commit | 22be59d16bdee1748b7d73f8c49dc4525c6cccff (patch) | |
tree | 7c1519483e577d51fcd7e505134d24ffbec285de | |
parent | 3a86e7a7c7d9d44d564ebadee134dd981118ba14 (diff) | |
download | e2fsprogs-22be59d16bdee1748b7d73f8c49dc4525c6cccff.tar.gz |
e2fsck: validate fscrypt_symlink_data.len for fast symlinks too
Both fast and slow encrypted symlinks are prefixed with the ciphertext
length field (fscrypt_symlink_data.len). But e2fsck was only checking
it for slow symlinks. Start checking it for fast symlinks too. This
matches the kernel handling of encrypted symlinks.
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r-- | e2fsck/pass1.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 723acf099..d9df28edb 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -183,6 +183,7 @@ int e2fsck_pass1_check_device_inode(ext2_filsys fs EXT2FS_ATTR((unused)), int e2fsck_pass1_check_symlink(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, char *buf) { + unsigned int buflen; unsigned int len; int i; ext2_extent_handle_t handle; @@ -232,9 +233,8 @@ int e2fsck_pass1_check_symlink(ext2_filsys fs, ext2_ino_t ino, if (inode->i_size >= sizeof(inode->i_block)) return 0; - len = strnlen((char *)inode->i_block, sizeof(inode->i_block)); - if (len == sizeof(inode->i_block)) - return 0; + buf = (char *)inode->i_block; + buflen = sizeof(inode->i_block); } else { if ((inode->i_size >= fs->blocksize) || (inode->i_block[0] < fs->super->s_first_data_block) || @@ -248,14 +248,17 @@ int e2fsck_pass1_check_symlink(ext2_filsys fs, ext2_ino_t ino, if (io_channel_read_blk64(fs->io, inode->i_block[0], 1, buf)) return 0; - if (inode->i_flags & EXT4_ENCRYPT_FL) { - len = ext2fs_le16_to_cpu(*((__u16 *)buf)) + 2; - } else { - len = strnlen(buf, fs->blocksize); - } - if (len >= fs->blocksize) - return 0; + buflen = fs->blocksize; } + + if (inode->i_flags & EXT4_ENCRYPT_FL) + len = ext2fs_le16_to_cpu(*(__u16 *)buf) + 2; + else + len = strnlen(buf, buflen); + + if (len >= buflen) + return 0; + if (len != inode->i_size) if ((inode->i_flags & EXT4_ENCRYPT_FL) == 0) return 0; |