* [PATCH] ext4: Verify fast symlink length
@ 2025-02-06 9:44 Jan Kara
2025-02-06 15:24 ` Theodore Ts'o
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Jan Kara @ 2025-02-06 9:44 UTC (permalink / raw)
To: Ted Tso; +Cc: linux-ext4, Jan Kara, syzbot+48a99e426f29859818c0,
Darrick J. Wong
Verify fast symlink length stored in inode->i_size matches the string
stored in the inode to avoid surprises from corrupted filesystems.
Reported-by: syzbot+48a99e426f29859818c0@syzkaller.appspotmail.com
Tested-by: syzbot+48a99e426f29859818c0@syzkaller.appspotmail.com
Fixes: bae80473f7b0 ("ext4: use inode_set_cached_link()")
Suggested-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Jan Kara <jack@suse.cz>
---
fs/ext4/inode.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 7c54ae5fcbd4..64e280fed911 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5007,8 +5007,16 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
inode->i_op = &ext4_encrypted_symlink_inode_operations;
} else if (ext4_inode_is_fast_symlink(inode)) {
inode->i_op = &ext4_fast_symlink_inode_operations;
- nd_terminate_link(ei->i_data, inode->i_size,
- sizeof(ei->i_data) - 1);
+ if (inode->i_size == 0 ||
+ inode->i_size >= sizeof(ei->i_data) ||
+ strnlen((char *)ei->i_data, inode->i_size + 1) !=
+ inode->i_size) {
+ ext4_error_inode(inode, function, line, 0,
+ "invalid fast symlink length %llu",
+ (unsigned long long)inode->i_size);
+ ret = -EFSCORRUPTED;
+ goto bad_inode;
+ }
inode_set_cached_link(inode, (char *)ei->i_data,
inode->i_size);
} else {
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] ext4: Verify fast symlink length
2025-02-06 9:44 [PATCH] ext4: Verify fast symlink length Jan Kara
@ 2025-02-06 15:24 ` Theodore Ts'o
2025-02-06 16:04 ` Eric Biggers
2025-02-07 12:54 ` Jan Kara
2025-02-06 15:34 ` Darrick J. Wong
` (2 subsequent siblings)
3 siblings, 2 replies; 7+ messages in thread
From: Theodore Ts'o @ 2025-02-06 15:24 UTC (permalink / raw)
To: Jan Kara; +Cc: linux-ext4, syzbot+48a99e426f29859818c0, Darrick J. Wong
On Thu, Feb 06, 2025 at 10:44:55AM +0100, Jan Kara wrote:
> Verify fast symlink length stored in inode->i_size matches the string
> stored in the inode to avoid surprises from corrupted filesystems.
>
> Reported-by: syzbot+48a99e426f29859818c0@syzkaller.appspotmail.com
> Tested-by: syzbot+48a99e426f29859818c0@syzkaller.appspotmail.com
> Fixes: bae80473f7b0 ("ext4: use inode_set_cached_link()")
> Suggested-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: Jan Kara <jack@suse.cz>
> ---
> fs/ext4/inode.c | 12 ++++++++++--
> 1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index 7c54ae5fcbd4..64e280fed911 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -5007,8 +5007,16 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
> inode->i_op = &ext4_encrypted_symlink_inode_operations;
> } else if (ext4_inode_is_fast_symlink(inode)) {
> inode->i_op = &ext4_fast_symlink_inode_operations;
> - nd_terminate_link(ei->i_data, inode->i_size,
> - sizeof(ei->i_data) - 1);
> + if (inode->i_size == 0 ||
> + inode->i_size >= sizeof(ei->i_data) ||
> + strnlen((char *)ei->i_data, inode->i_size + 1) !=
> + inode->i_size) {
> + ext4_error_inode(inode, function, line, 0,
> + "invalid fast symlink length %llu",
> + (unsigned long long)inode->i_size);
> + ret = -EFSCORRUPTED;
> + goto bad_inode;
> + }
> inode_set_cached_link(inode, (char *)ei->i_data,
> inode->i_size);
I don't think this will do the right thing if the fast symlink is
encrypted. See ext4_encrypted_get_link() in fs/ext4/symlink.c in the
kernel sources, and also look at how e2fsck_pass1_check_symlink()
handles checking the size of an encrypted, fast symlink.
Thanks,
- Ted
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] ext4: Verify fast symlink length
2025-02-06 9:44 [PATCH] ext4: Verify fast symlink length Jan Kara
2025-02-06 15:24 ` Theodore Ts'o
@ 2025-02-06 15:34 ` Darrick J. Wong
2025-02-10 13:50 ` Baokun Li
2025-03-18 3:41 ` Theodore Ts'o
3 siblings, 0 replies; 7+ messages in thread
From: Darrick J. Wong @ 2025-02-06 15:34 UTC (permalink / raw)
To: Jan Kara; +Cc: Ted Tso, linux-ext4, syzbot+48a99e426f29859818c0
On Thu, Feb 06, 2025 at 10:44:55AM +0100, Jan Kara wrote:
> Verify fast symlink length stored in inode->i_size matches the string
> stored in the inode to avoid surprises from corrupted filesystems.
>
> Reported-by: syzbot+48a99e426f29859818c0@syzkaller.appspotmail.com
> Tested-by: syzbot+48a99e426f29859818c0@syzkaller.appspotmail.com
> Fixes: bae80473f7b0 ("ext4: use inode_set_cached_link()")
> Suggested-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: Jan Kara <jack@suse.cz>
> ---
> fs/ext4/inode.c | 12 ++++++++++--
> 1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index 7c54ae5fcbd4..64e280fed911 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -5007,8 +5007,16 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
> inode->i_op = &ext4_encrypted_symlink_inode_operations;
> } else if (ext4_inode_is_fast_symlink(inode)) {
> inode->i_op = &ext4_fast_symlink_inode_operations;
> - nd_terminate_link(ei->i_data, inode->i_size,
> - sizeof(ei->i_data) - 1);
> + if (inode->i_size == 0 ||
> + inode->i_size >= sizeof(ei->i_data) ||
> + strnlen((char *)ei->i_data, inode->i_size + 1) !=
> + inode->i_size) {
Oooh, a validation I overlooked! :D
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> + ext4_error_inode(inode, function, line, 0,
> + "invalid fast symlink length %llu",
> + (unsigned long long)inode->i_size);
> + ret = -EFSCORRUPTED;
> + goto bad_inode;
> + }
> inode_set_cached_link(inode, (char *)ei->i_data,
> inode->i_size);
> } else {
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] ext4: Verify fast symlink length
2025-02-06 15:24 ` Theodore Ts'o
@ 2025-02-06 16:04 ` Eric Biggers
2025-02-07 12:54 ` Jan Kara
1 sibling, 0 replies; 7+ messages in thread
From: Eric Biggers @ 2025-02-06 16:04 UTC (permalink / raw)
To: Theodore Ts'o
Cc: Jan Kara, linux-ext4, syzbot+48a99e426f29859818c0,
Darrick J. Wong
On Thu, Feb 06, 2025 at 10:24:19AM -0500, Theodore Ts'o wrote:
> On Thu, Feb 06, 2025 at 10:44:55AM +0100, Jan Kara wrote:
> > Verify fast symlink length stored in inode->i_size matches the string
> > stored in the inode to avoid surprises from corrupted filesystems.
> >
> > Reported-by: syzbot+48a99e426f29859818c0@syzkaller.appspotmail.com
> > Tested-by: syzbot+48a99e426f29859818c0@syzkaller.appspotmail.com
> > Fixes: bae80473f7b0 ("ext4: use inode_set_cached_link()")
> > Suggested-by: "Darrick J. Wong" <djwong@kernel.org>
> > Signed-off-by: Jan Kara <jack@suse.cz>
> > ---
> > fs/ext4/inode.c | 12 ++++++++++--
> > 1 file changed, 10 insertions(+), 2 deletions(-)
> >
> > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> > index 7c54ae5fcbd4..64e280fed911 100644
> > --- a/fs/ext4/inode.c
> > +++ b/fs/ext4/inode.c
> > @@ -5007,8 +5007,16 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
> > inode->i_op = &ext4_encrypted_symlink_inode_operations;
> > } else if (ext4_inode_is_fast_symlink(inode)) {
> > inode->i_op = &ext4_fast_symlink_inode_operations;
> > - nd_terminate_link(ei->i_data, inode->i_size,
> > - sizeof(ei->i_data) - 1);
> > + if (inode->i_size == 0 ||
> > + inode->i_size >= sizeof(ei->i_data) ||
> > + strnlen((char *)ei->i_data, inode->i_size + 1) !=
> > + inode->i_size) {
> > + ext4_error_inode(inode, function, line, 0,
> > + "invalid fast symlink length %llu",
> > + (unsigned long long)inode->i_size);
> > + ret = -EFSCORRUPTED;
> > + goto bad_inode;
> > + }
> > inode_set_cached_link(inode, (char *)ei->i_data,
> > inode->i_size);
>
>
> I don't think this will do the right thing if the fast symlink is
> encrypted. See ext4_encrypted_get_link() in fs/ext4/symlink.c in the
> kernel sources, and also look at how e2fsck_pass1_check_symlink()
> handles checking the size of an encrypted, fast symlink.
>
Encrypted symlinks are handled separately just a couple lines above.
- Eric
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] ext4: Verify fast symlink length
2025-02-06 15:24 ` Theodore Ts'o
2025-02-06 16:04 ` Eric Biggers
@ 2025-02-07 12:54 ` Jan Kara
1 sibling, 0 replies; 7+ messages in thread
From: Jan Kara @ 2025-02-07 12:54 UTC (permalink / raw)
To: Theodore Ts'o
Cc: Jan Kara, linux-ext4, syzbot+48a99e426f29859818c0,
Darrick J. Wong
On Thu 06-02-25 10:24:19, Theodore Ts'o wrote:
> On Thu, Feb 06, 2025 at 10:44:55AM +0100, Jan Kara wrote:
> > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> > index 7c54ae5fcbd4..64e280fed911 100644
> > --- a/fs/ext4/inode.c
> > +++ b/fs/ext4/inode.c
> > @@ -5007,8 +5007,16 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
> > inode->i_op = &ext4_encrypted_symlink_inode_operations;
> > } else if (ext4_inode_is_fast_symlink(inode)) {
> > inode->i_op = &ext4_fast_symlink_inode_operations;
> > - nd_terminate_link(ei->i_data, inode->i_size,
> > - sizeof(ei->i_data) - 1);
> > + if (inode->i_size == 0 ||
> > + inode->i_size >= sizeof(ei->i_data) ||
> > + strnlen((char *)ei->i_data, inode->i_size + 1) !=
> > + inode->i_size) {
> > + ext4_error_inode(inode, function, line, 0,
> > + "invalid fast symlink length %llu",
> > + (unsigned long long)inode->i_size);
> > + ret = -EFSCORRUPTED;
> > + goto bad_inode;
> > + }
> > inode_set_cached_link(inode, (char *)ei->i_data,
> > inode->i_size);
>
>
> I don't think this will do the right thing if the fast symlink is
> encrypted. See ext4_encrypted_get_link() in fs/ext4/symlink.c in the
> kernel sources, and also look at how e2fsck_pass1_check_symlink()
> handles checking the size of an encrypted, fast symlink.
Thanks for having a look but as Eric writes, there's:
if (IS_ENCRYPTED(inode)) {
inode->i_op = &ext4_encrypted_symlink_inode_operations;
} else if (ext4_inode_is_fast_symlink(inode)) {
just above the context of this hunk so I *think* encrypted symlinks cannot
get into this code?
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] ext4: Verify fast symlink length
2025-02-06 9:44 [PATCH] ext4: Verify fast symlink length Jan Kara
2025-02-06 15:24 ` Theodore Ts'o
2025-02-06 15:34 ` Darrick J. Wong
@ 2025-02-10 13:50 ` Baokun Li
2025-03-18 3:41 ` Theodore Ts'o
3 siblings, 0 replies; 7+ messages in thread
From: Baokun Li @ 2025-02-10 13:50 UTC (permalink / raw)
To: Jan Kara
Cc: Ted Tso, linux-ext4, syzbot+48a99e426f29859818c0, Darrick J. Wong,
Yang Erkun
On 2025/2/6 17:44, Jan Kara wrote:
> Verify fast symlink length stored in inode->i_size matches the string
> stored in the inode to avoid surprises from corrupted filesystems.
>
> Reported-by: syzbot+48a99e426f29859818c0@syzkaller.appspotmail.com
> Tested-by: syzbot+48a99e426f29859818c0@syzkaller.appspotmail.com
> Fixes: bae80473f7b0 ("ext4: use inode_set_cached_link()")
> Suggested-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: Jan Kara <jack@suse.cz>
> ---
Looks good to me, thanks for the patch!
Reviewed-by: Baokun Li <libaokun1@huawei.com>
> fs/ext4/inode.c | 12 ++++++++++--
> 1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index 7c54ae5fcbd4..64e280fed911 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -5007,8 +5007,16 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
> inode->i_op = &ext4_encrypted_symlink_inode_operations;
> } else if (ext4_inode_is_fast_symlink(inode)) {
> inode->i_op = &ext4_fast_symlink_inode_operations;
> - nd_terminate_link(ei->i_data, inode->i_size,
> - sizeof(ei->i_data) - 1);
> + if (inode->i_size == 0 ||
> + inode->i_size >= sizeof(ei->i_data) ||
> + strnlen((char *)ei->i_data, inode->i_size + 1) !=
> + inode->i_size) {
> + ext4_error_inode(inode, function, line, 0,
> + "invalid fast symlink length %llu",
> + (unsigned long long)inode->i_size);
> + ret = -EFSCORRUPTED;
> + goto bad_inode;
> + }
> inode_set_cached_link(inode, (char *)ei->i_data,
> inode->i_size);
> } else {
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] ext4: Verify fast symlink length
2025-02-06 9:44 [PATCH] ext4: Verify fast symlink length Jan Kara
` (2 preceding siblings ...)
2025-02-10 13:50 ` Baokun Li
@ 2025-03-18 3:41 ` Theodore Ts'o
3 siblings, 0 replies; 7+ messages in thread
From: Theodore Ts'o @ 2025-03-18 3:41 UTC (permalink / raw)
To: Jan Kara
Cc: Theodore Ts'o, linux-ext4, syzbot+48a99e426f29859818c0,
Darrick J. Wong
On Thu, 06 Feb 2025 10:44:55 +0100, Jan Kara wrote:
> Verify fast symlink length stored in inode->i_size matches the string
> stored in the inode to avoid surprises from corrupted filesystems.
>
>
Applied, thanks!
[1/1] ext4: Verify fast symlink length
commit: 5f920d5d60839f7cbbb1ed50eac68d8bc0a73a7c
Best regards,
--
Theodore Ts'o <tytso@mit.edu>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-03-18 3:42 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-06 9:44 [PATCH] ext4: Verify fast symlink length Jan Kara
2025-02-06 15:24 ` Theodore Ts'o
2025-02-06 16:04 ` Eric Biggers
2025-02-07 12:54 ` Jan Kara
2025-02-06 15:34 ` Darrick J. Wong
2025-02-10 13:50 ` Baokun Li
2025-03-18 3:41 ` Theodore Ts'o
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox