Re: Bogus buffer length check in linux-2.6.11 read()

linux-os
2005-03-16T14:55:51Z

Brilliant! And it even works!
Now if the kernel hadn't screwed up in the first place, then
your expertise wouldn't have been needed.

Thanks.

On Wed, 16 Mar 2005, Eric Dumazet wrote:

> linux-os wrote:
>
>>
>>
>> I don't know how much more precise I could have been. I show the
>> code that will cause the observed condition. I explain that this
>> condition is new, that it doesn't correspond to the previous
>> behavior.
>>
>> Never before was some buffer checked for length before some data
>> was written to it. The EFAULT is supposed to occur IFF a write
>> attempt occurs outside the caller's accessible address space.
>> This used to be done by hardware during the write to user-space.
>> This had zero impact upon performance. Now there is some
>> software added that adds CPU cycles, subtracts performance,
>> and cannot possibly do anything useful.
>>
>> Also, the code was written to show the problem. The code
>> is not designed to be an example of good coding practice.
>>
>> The actual problem observed with the new kernel was
>> when some legacy code used gets() instead of fgets().
>> The call returned immediately with an EFAULT because
>> the 'C' runtime library put some value that the kernel
>> didn't 'like' (4096 bytes) in the subsequent read.
>
>
> If you use a buggy program, that had a hidden bug now exposed because of
> different kernel checks, dont complain, and use your brain.
>
> If you do
>
> $ export VAR1=" A very very very very long chain just to be sure my
> environnement (which is placed at the top of the stack at exec() time) will
> use at least 4 Kb : then my litle buggy program will run if I type few chars
> but destroy my stack if I type a long string or if I use : cat longfile |
> ./xxx : So I wont complain again on lkml that I am sooooo lazy. Oh what could
> I type now, I'm tired, maybe I can copy this string to others variables.
> Yes... sure...."
> $ export VAR2=$VAR1
> $ export VAR3=$VAR1
> $ export VAR4=$VAR1
> $ export VAR5=$VAR1
> Then check your env size is large enough
> $ env|wc -c
> 4508
> $ ./xxx
> ./xxx 2>/dev/null
>
> Apparently the kernel thinks 4096 is a good length!
>
> So what ? Your program works well now, on a linux-2.6.11 typical machine.
> Ready to buffer overflow again.
>
> Maybe you can pay me $1000 :)
>
> Eric Dumazet
>>
>> This is code for which there are no sources available
>> and it is required to be used, cannot be replaced,
>> cannot be thrown away and costs about US$ 10,000
>> from a company that is no longer in business.
>>
>> Somebody's arbitrary and capricious addition of spook
>> code destroyed an application's functionality.
>>
>> Cheers,
>> Dick Johnson