Python, Linux, and the setuid bit

Chris Angelico rosuav at gmail.com
Tue Apr 15 04:15:11 EDT 2014


On Tue, Apr 15, 2014 at 6:00 PM, Richard Kettlewell <rjk at greenend.org.uk> wrote:
> Ethan Furman <ethan at stoneleaf.us> writes:
>>         memset(envp_write, 0, ((unsigned int) envp_read -
>>                                (unsigned int) envp_write));
>
> That is a remarkable blunder for a security-critical program.
>
> On a 64-bit platform, the best case outcome is that it will throw away
> the top 32 bits of each pointer before doing the subtraction, yielding
> the wrong answer if the discarded bits happen to differ.

If the pointers are more than 4GB apart, then yes, it'll give the
wrong answer - just as if you'd subtracted and then cast down to an
integer too small for the result. But if they're two pointers inside
the same object (already a requirement for pointer arithmetic) and not
4GB apart, then two's complement arithmetic will give the right result
even if the discarded bits differ. So while you're correct in theory,
in practice it's unlikely to actually be a problem.

> (There is no limit to the worst case behavior; the effect of converting
> a pointer value to an integer type which cannot represent the result is
> undefined.)
>
> I would write:
>
>   (envp_read - envp_write) * sizeof *envp_read

I'd simply cast them to (char *), which will permit the arithmetic
quite happily and look cleaner.

ChrisA



More information about the Python-list mailing list