aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2018-03-02 16:59:18 -0800
committerTheodore Ts'o <tytso@mit.edu>2018-03-03 16:39:59 -0500
commit22be59d16bdee1748b7d73f8c49dc4525c6cccff (patch)
tree7c1519483e577d51fcd7e505134d24ffbec285de
parent3a86e7a7c7d9d44d564ebadee134dd981118ba14 (diff)
downloade2fsprogs-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.c23
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;