Re: [PATCH] amd64: Fix csum_partial_copy_generic()

From: Thomas Gleixner
Date: Wed Oct 18 2023 - 11:13:04 EST


On Wed, Oct 18 2023 at 09:36, Eric Dumazet wrote:
> On Wed, Oct 18, 2023 at 8:18 AM gus Gusenleitner Klaus <gus@xxxxxxxx> wrote:
>>
>> The checksum calculation is wrong in case of an source buffer
>> containing zero bytes only. The expected return value is 0, the
>> actual return value is 0xfffffff.
>>
>> This problem occurs when a ICMP echo reply is sent that has set
>> zero identifier, sequence number and data.
>>
>> Signed-off-by: Klaus Gusenleitner <gus@xxxxxxxx>
>> ---
>> arch/x86/lib/csum-copy_64.S | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/x86/lib/csum-copy_64.S b/arch/x86/lib/csum-copy_64.S
>> index d9e16a2cf285..c8391b4f3dea 100644
>> --- a/arch/x86/lib/csum-copy_64.S
>> +++ b/arch/x86/lib/csum-copy_64.S
>> @@ -44,7 +44,7 @@ SYM_FUNC_START()
>> movq %r13, 3*8(%rsp)
>> movq %r15, 4*8(%rsp)
>>
>> - movl $-1, %eax
>> + movl $0, %eax

I don't think this is correct. See below.

>> xorl %r9d, %r9d
>> movl %edx, %ecx
>> cmpl $8, %ecx
>> --
>> 2.30.2
>>
>
> Lets CC Noah Goldstein <goldstein.w.n@xxxxxxxxx> (I thought Noah wrote
> some kunit tests, maybe I am wrong)
>
> When was this bug added ?

AFAICT, this was introduced with:

daf52375c19f ("amd64: switch csum_partial_copy_generic() to new calling conventions")

> A Fixes: tag is very much needed, and would be a needed step to CC the
> original author.

Cc'ed Al.

So the change in question is:

- movl %ecx, %eax // Original code stores ECX in EAX
+ movl $-1, %eax // EAX is preset with -1

ECX (RCX) was the 4th parameter of the original ASM function call:

extern __visible __wsum csum_partial_copy_generic(const void *src, const void *dst,
int len, __wsum sum,
int *src_err_ptr, int *dst_err_ptr);

I.e. it handed @sum into the function which means a caller provided
seed.

With the above patch the ASM function call was changed to

extern __visible __wsum csum_partial_copy_generic(const void *src, void *dst, int len);

I.e. the seed parameter was removed. AFAICT, all callers back then initialized
the seed parameter to 0 via the various wrapper interfaces which end up there.

Al?

Thanks,

tglx