qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Clemens Kolbitsch <ck@iseclab.org>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] i386 emulation bug: mov reg, [addr]
Date: Tue, 15 Dec 2009 19:48:53 +0100	[thread overview]
Message-ID: <200912151948.53307.ck@iseclab.org> (raw)

Hi list,

I'm experiencing a strange emulation bug with the op-code below. The 
instruction raises a segfault in the application (running on the guest), 
however, if I enable KVM to run the exact same application, no segfault is 
raised.

0x0080023b:       8b 04 65 11 22 33 44    mov regEAX, [0x44332211]

where "11 22 33 44" is just some address. According to gdb (on a 32bit little-
endian machine), this instruction can be disassembled as a "mov address to 
reg-eax".

I have added some debugging code to the disas_insn function in translate.c to 
find out that the code is disassembled to the following blocks:

(NOTE: this debugging comes from an old qemu version where the old TB-style 
code was still used. HOWEVER, the same bug is still happening when used on the 
0.11.0 source branch).

0x0080023b: disassemble 7 bytes (to 0x00800242)
0x001: movl_A0_im 0x44332211
0x002: addl_A0_ESP_s1
0x003: ldl_user_T0_A0
0x004: movl_EAX_T0

So, as you can see, everything seems correct, but there is an additional 
(second) TB that messes everything up. In fact, the segfault happens because 
whatever is in ESP (shifted by one) is added to the address (which might then 
not be a valid address).

As I said, the code might crash in old versions of Qemu just like in the 
0.11.0 source branch and works fine if I use KVM (because the user code is not 
emulated of course).

Since this is such a fundamental problem, I don't quite understand how this 
could stay hidden so long... or maybe there is an error on my side :-/

Any help on this is greatly appreciated!!
--Clemens


---

some additional debugging information: I have traced down the problem to the 
following call in translate.c:

static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int 
*offset_ptr)
{
    ...
    if (s->aflag) {
        /// !!!!!!!!!! we take this path !!!!!!!!!!!!!!
        ...

        if (base == 4) {
            /// !!!!!!!!!! we take this path !!!!!!!!!!!!!!
            havesib = 1;
            code = ldub_code(s->pc++);
            scale = (code >> 6) & 3;
            index = ((code >> 3) & 7) | REX_X(s);
            base = (code & 7);
        }
        base |= REX_B(s);

        switch (mod) {
        ...
        default:
        case 2:
            /// !!!!!!!!!! 4byte load: we take this path !!!!!!!!!!!!!!
            disp = ldl_code(s->pc);
            s->pc += 4;
            break;
        }

        if (base >= 0) {
            /* for correct popl handling with esp */
            ...
        } else {
#ifdef TARGET_X86_64
            if (s->aflag == 2) {
                gen_op_movq_A0_im(disp);
            } else
#endif
            {
                /// !!!!!!!!!! this is still ok, we need the address !!!!!!!
                gen_op_movl_A0_im(disp);
            }
        }
        /* XXX: index == 4 is always invalid */
        if (havesib && (index != 4 || scale != 0)) {
#ifdef TARGET_X86_64
            if (s->aflag == 2) {
                gen_op_addq_A0_reg_sN(scale, index);
            } else
#endif
            {
                /// !!!!!!!!!! this does the evil !!!!!!!!!!!!!!
                gen_op_addl_A0_reg_sN(scale, index);
            }
        }

             reply	other threads:[~2009-12-15 18:50 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-15 18:48 Clemens Kolbitsch [this message]
2009-12-15 19:54 ` [Qemu-devel] i386 emulation bug: mov reg, [addr] Avi Kivity
2009-12-15 21:21   ` Jamie Lokier
2009-12-16  8:56   ` Clemens Kolbitsch
2009-12-16  9:05     ` Avi Kivity
2009-12-16  9:28       ` [Qemu-devel] " Paolo Bonzini
2009-12-15 21:26 ` [Qemu-devel] " Jamie Lokier
2009-12-15 22:24   ` malc
2009-12-15 23:37   ` [Qemu-devel] " Paolo Bonzini
2009-12-16 10:07   ` [Qemu-devel] " Avi Kivity
2010-03-06 17:02 ` Aurelien Jarno

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200912151948.53307.ck@iseclab.org \
    --to=ck@iseclab.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).