[PATCH] new x86 personality detection

Dmitry V. Levin ldv at altlinux.org
Tue Feb 12 00:51:08 UTC 2013


On Mon, Feb 11, 2013 at 03:12:23PM +0100, Denys Vlasenko wrote:
> On 02/11/2013 01:46 PM, Denys Vlasenko wrote:
> > On 02/11/2013 12:45 PM, Denys Vlasenko wrote:
> >> This patch implements a (hopefully) correct way to check for
> >> syscall bitness on x86.
> >>
> >> I tested it to work when stracing normal 32-bit binaries,
> >> can't test the above example till this evening.
> >> But it should work too (famous last words?).
> >>
> >> Please review.
> > 
> > Looks like we had a bug on X32:
> > 
> > 	if (check_errno && is_negated_errno(x86_64_regs.rax)) {
> > 
> > If we build in X32 environment, above we check only lower 32 bits of rax
> > - because is_negated_errno() takes _long_ parameter, which is 32-bit
> > on X32. Therefore e.g. llseek returning a valid offset of 0xfffffffe
> > will be mishandled as returning errno 2.
> > 
> > The updated patch also includes fix for this bug.
> 
> ...the slight problem that my code... doesn't fix the bug :(
> 
> +is_negated_errno_ll(unsigned long long val)
> +{
> +	unsigned long long max = -(long long) nerrnos;
> +#if SUPPORTED_PERSONALITIES > 1
> +	if (current_wordsize < sizeof(val)) {
> +		val = (unsigned int) val;
> +		max = (unsigned int) max;
> +	}
> +#endif
> +	return val > max;
> +}
> 
> The above _always_ falls into "if", since current_wordsize == 4
> even for native X32.
> Looks like I'll have to resort to x32-specific checking function:
> 
> +static inline int
> +is_negated_errno_x32(unsigned long long val)
> +{
> +       unsigned long long max = -(long long) nerrnos;
> +       /*
> +        * current_wordsize == 4 even in personality 0 (X32)
> +        * but truncation _must not_ be done in it.
> +        * can't check current_wordsize here!
> +        */
> +       if (current_personality != 0) {
> +               val = (uint32_t) val;
> +               max = (uint32_t) max;
> +       }
> +       return val > max;
> +}

I suppose this is not necessarily limited to X32, it can happen on any
architecture with ext_arg and u_lrval.

Maybe i's worth introducing some kind of
personality_is_negated_errno[current_personality] and changing
is_negated_errno to a macro.


-- 
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20130212/bee96324/attachment.bin>


More information about the Strace-devel mailing list