[PATCH] btrfs: lzo: reject inline extents without both headers

David Lee posted 1 patch 1 week, 4 days ago
fs/btrfs/lzo.c |    3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
[PATCH] btrfs: lzo: reject inline extents without both headers
Posted by David Lee 1 week, 4 days ago
inline Btrfs LZO payload shorter than two LZO headers.

Fix the validation or lifetime rule at the vulnerable boundary so malformed
or racing input cannot reach the faulting path.

Signed-off-by: David Lee <david.lee@trailofbits.com>
Assisted-by: Codex:gpt-5.5
---
Trail of Bits has a reproducer for this bug demonstrating Kernel Panic which can be shared further if needed.

fs/btrfs/lzo.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c
--- a/fs/btrfs/lzo.c
+++ b/fs/btrfs/lzo.c
@@ -552,7 +552,8 @@ int lzo_decompress(struct list_head *ws, const u8 *data_in,
 	size_t max_segment_len = workspace_buf_length(fs_info);
 	int ret;
 
-	if (unlikely(srclen < LZO_LEN || srclen > max_segment_len + LZO_LEN * 2))
+	if (unlikely(srclen < LZO_LEN * 2 ||
+		     srclen > max_segment_len + LZO_LEN * 2))
 		return -EUCLEAN;
 
 	in_len = get_unaligned_le32(data_in);
Re: [PATCH] btrfs: lzo: reject inline extents without both headers
Posted by Qu Wenruo 1 week, 4 days ago

在 2026/7/14 16:40, David Lee 写道:
> inline Btrfs LZO payload shorter than two LZO headers.
> 
> Fix the validation or lifetime rule at the vulnerable boundary so malformed
> or racing input cannot reach the faulting path.
> 
> Signed-off-by: David Lee <david.lee@trailofbits.com>
> Assisted-by: Codex:gpt-5.5
> ---
> Trail of Bits has a reproducer for this bug demonstrating Kernel Panic which can be shared further if needed.
> 
> fs/btrfs/lzo.c |    3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c
> --- a/fs/btrfs/lzo.c
> +++ b/fs/btrfs/lzo.c
> @@ -552,7 +552,8 @@ int lzo_decompress(struct list_head *ws, const u8 *data_in,
>   	size_t max_segment_len = workspace_buf_length(fs_info);
>   	int ret;
>   
> -	if (unlikely(srclen < LZO_LEN || srclen > max_segment_len + LZO_LEN * 2))
> +	if (unlikely(srclen < LZO_LEN * 2 ||

srclen == LZO_LEN * 2 is also invalid, as that means the lzo payload is 
empty.


Also your base is a little too old.

The latest for-next branch has extra error messages, thus your patch 
doesn't apply cleanly.

Please rebase to the latest for-next branch:

  https://github.com/btrfs/linux.git for-next

Otherwise the fix looks good to me.

Thanks,
Qu

> +		     srclen > max_segment_len + LZO_LEN * 2))
>   		return -EUCLEAN;
>   
>   	in_len = get_unaligned_le32(data_in);
> 
> 
Re: [PATCH] btrfs: lzo: reject inline extents without both headers
Posted by Qu Wenruo 1 week, 4 days ago

在 2026/7/14 18:08, Qu Wenruo 写道:
> 
> 
> 在 2026/7/14 16:40, David Lee 写道:
>> inline Btrfs LZO payload shorter than two LZO headers.
>>
>> Fix the validation or lifetime rule at the vulnerable boundary so 
>> malformed
>> or racing input cannot reach the faulting path.
>>
>> Signed-off-by: David Lee <david.lee@trailofbits.com>
>> Assisted-by: Codex:gpt-5.5
>> ---
>> Trail of Bits has a reproducer for this bug demonstrating Kernel Panic 
>> which can be shared further if needed.

Also forgot to mention, it's always better to provide the full calltrace.

It will benefit people who hit a similar crash to determine if it's 
already fixed.
>>
>> fs/btrfs/lzo.c |    3 ++-
>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c
>> --- a/fs/btrfs/lzo.c
>> +++ b/fs/btrfs/lzo.c
>> @@ -552,7 +552,8 @@ int lzo_decompress(struct list_head *ws, const u8 
>> *data_in,
>>       size_t max_segment_len = workspace_buf_length(fs_info);
>>       int ret;
>> -    if (unlikely(srclen < LZO_LEN || srclen > max_segment_len + 
>> LZO_LEN * 2))
>> +    if (unlikely(srclen < LZO_LEN * 2 ||
> 
> srclen == LZO_LEN * 2 is also invalid, as that means the lzo payload is 
> empty.
> 
> 
> Also your base is a little too old.
> 
> The latest for-next branch has extra error messages, thus your patch 
> doesn't apply cleanly.
> 
> Please rebase to the latest for-next branch:
> 
>   https://github.com/btrfs/linux.git for-next
> 
> Otherwise the fix looks good to me.
> 
> Thanks,
> Qu
> 
>> +             srclen > max_segment_len + LZO_LEN * 2))
>>           return -EUCLEAN;
>>       in_len = get_unaligned_le32(data_in);
>>
>>
> 
>