[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