Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failure to sandbox x64 absolute addr write #841

Closed
derekbruening opened this issue Nov 28, 2014 · 6 comments
Closed

Failure to sandbox x64 absolute addr write #841

derekbruening opened this issue Nov 28, 2014 · 6 comments

Comments

@derekbruening
Copy link
Contributor

From [email protected] on July 12, 2012 10:49:37

This only started happening recently. I don't know what changed to cause this.

I get this assert when I run DR on asan-ified DRT:
<Application DumpRenderTree (7826) DynamoRIO usage error : opnd_get_index called on invalid opnd type>

This was the stack:
(gdb) bt
#0 read_syscall (fd=0, buf=0x41bfdadf, nbytes=1) at ../core/linux/os.c:3363
#1 0x00000000712a8152 in os_read (f=0, buf=0x41bfdadf, count=1) at ../core/linux/os.c:3556
#2 0x0000000071113b03 in notify (priority=SYSLOG_ERROR, internal=false, synch=true, substitution_num=4, prefix=0x71300c00 "SYSLOG_ERROR", fmt=0x71300bd8 "Application %s (%s) %s usage error : %s") at ../core/utils.c:1878
#3 0x000000007110ebee in external_error (file=0x71333442 "../core/x86/instr.c", line=550, msg=0x71333930 "opnd_get_index called on invalid opnd type") at ../core/utils.c:203
#4 0x000000007123022c in opnd_get_index (opnd=...) at ../core/x86/instr.c:550
#5 0x0000000071211e8f in encode_base_disp (di=0x41bfe5b0, opnd=...) at ../core/x86/encode.c:1518
#6 0x0000000071212797 in encode_operand (di=0x41bfe5b0, optype=10, opsize=141 '\215', opnd=...) at ../core/x86/encode.c:1746
#7 0x00000000712146ea in instr_encode_common (dcontext=0x41bbc340, instr=0x41c22908,
copy_pc=0x41c017e0 "\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\005",
final_pc=0x41c017e0 "\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\005", check_reachable=true, assert_reachable=false) at ../core/x86/encode.c:2349
#8 0x0000000071215114 in instr_encode_check_reachability (dcontext=0x41bbc340, instr=0x41c22908,
pc=0x41c017e0 "\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\274\005") at ../core/x86/encode.c:2632
#9 0x0000000071233ab6 in private_instr_encode (dcontext=0x41bbc340, instr=0x41c22908, always_cache=false) at ../core/x86/instr.c:1899
#10 0x0000000071235496 in instr_length (dcontext=0x41bbc340, instr=0x41c22908) at ../core/x86/instr.c:2845
#11 0x0000000071107c91 in emit_fragment_common (dcontext=0x41bbc340, tag=0xb55034112f6 "ATH\213\305H\243x\223\330\310&\177", ilist=0x41c1f978, flags=32896, vmlist=0x451dcb88, link_fragment=true, add_to_htable=true, replace_fragment=0x0)
at ../core/emit.c:469
#12 0x000000007110e652 in emit_fragment_ex (dcontext=0x41bbc340, tag=0xb55034112f6 "ATH\213\305H\243x\223\330\310&\177", ilist=0x41c1f978, flags=32896, vmlist=0x451dcb88, link=true, visible=true) at ../core/emit.c:1012
#13 0x000000007124d6ee in build_basic_block_fragment (dcontext=0x41bbc340, start=0xb55034112f6 "ATH\213\305H\243x\223\330\310&\177", initial_flags=0, link=true, visible=true, for_trace=false, unmangled_ilist=0x0)
at ../core/x86/interp.c:4265
#14 0x00000000710f93a8 in dispatch (dcontext=0x41bbc340) at ../core/dispatch.c:187

(gdb) x/20i 0xb55034112f6
0xb55034112f6: push % r12 0xb55034112f8: mov %rbp,%rax
0xb55034112fb: movabs %rax,0x7f26c8d89378
0xb5503411305: jmpq 0xb550341130c
0xb550341130a: pushq $0x0
0xb550341130c: jmpq 0xb550341132a
0xb5503411311: movabs %rax,0x7f26c8d89320
0xb550341131b: movabs $0x7,%rax
0xb5503411325: jmpq 0xb5503411388
0xb550341132a: pushq $0x0
0xb550341132c: pushq $0x0
0xb550341132e: pushq $0x0
0xb5503411330: movabs $0xb5503411241,% r10 0xb550341133a: push % r10 0xb550341133c: movabs $0x7f26c8d89370,% r10 0xb5503411346: pushq (% r10 )
0xb5503411349: movabs $0x7f26c8d89370,% r10 0xb5503411353: mov %rsp,(% r10 )
0xb5503411356: mov -0x50(% r13 ),%rax
0xb550341135a: movabs %rax,0x7f26c8d89320

This code looks suspicious:
case TYPE_V_MODRM: /* we already ensured this is a reg, not memory */
...
#ifdef X64
if (opnd_is_rel_addr(opnd))
encode_rel_addr(di, opnd);
else
#endif
encode_base_disp(di, opnd);

Should we be checking for ABS_ADDR_kind here, or is the bug in assigning this operand TYPE_V_MODRM? I don't have the encoding of the instruction to paste at the moment. Trying to repro with a smaller app.

Original issue: http://code.google.com/p/dynamorio/issues/detail?id=841

@derekbruening
Copy link
Contributor Author

From [email protected] on July 12, 2012 10:54:45

I added this test to api.ir, and it fails:

static void
test_x64_abs_addr(void dc)
{
instr_t *instr;
opnd_t abs_addr = opnd_create_abs_addr((void
)0xdeadbeefdeadbeef, OPSZ_8);

print("testing movabs load\n");

/* movabs load */
instr = INSTR_CREATE_mov_ld(dc, opnd_create_reg(DR_REG_RAX), abs_addr);
test_instr_encode(dc, instr, 10);  /* REX + op + 8 */
print("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
      buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7],
      buf[8], buf[9]);

print("testing movabs store\n");

/* movabs store */
instr = INSTR_CREATE_mov_st(dc, abs_addr, opnd_create_reg(DR_REG_RAX));
test_instr_encode(dc, instr, 10);  /* REX + op + 8 */
print("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
      buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7],
      buf[8], buf[9]);

}

I believe these should encode as:
48 a1 (8 byte little endian abs addr)
48 a3 (8 byte little endian abs addr)

Which is the code that I observe generated by V8 in DRT.

I'm currently trying to understand why the 0xa1 encoding doesn't succeed for the load.

Owner: [email protected]

@derekbruening
Copy link
Contributor Author

From [email protected] on July 12, 2012 11:08:07

Nevermind, the api.ir test works fine. It was failing because I ran it after test_x86_mode, which leaves the dcontext in x86 mode. :( However, I do have a failing test case that uses self-mod and absolute addr operands. I'll keep looking into that.

@derekbruening
Copy link
Contributor Author

From [email protected] on July 12, 2012 11:26:15

the instruction with the assert in the first comment looks like OP_lea, right? why is there a lea in there? from selfmod mangling?

@derekbruening
Copy link
Contributor Author

From [email protected] on July 12, 2012 11:36:29

The real problem is that when we do sandboxing, we assume we can just lea the memory operand to get it's address. Here's the code that breaks:
/* change to OPSZ_lea for lea */
opnd_set_size(&op, OPSZ_lea);
PRE(ilist, next,
INSTR_CREATE_lea(dcontext, opnd_create_reg(REG_XBX), op));

When op is a 64-bit abs address, that doesn't work. mov $0xaddr, %rbx won't work either. However, sandboxing this write is kind of crazy, considering that it is an absolute reference and we know that while it's on the same page as the current app code, we can just test at sandboxing time if it's in the current fragment or not.

@derekbruening
Copy link
Contributor Author

From [email protected] on July 13, 2012 07:32:25

Summary: Failure to sandbox x64 absolute addr write

@derekbruening
Copy link
Contributor Author

From [email protected] on July 13, 2012 08:09:44

This issue was closed by revision r1464 .

Status: Fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant