Skip to content

Commit

Permalink
Merge branch 'master' of ssh://github.com/zyedidia/lfi
Browse files Browse the repository at this point in the history
  • Loading branch information
zyedidia committed Nov 28, 2024
2 parents cba9d08 + 118b631 commit f334810
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 53 deletions.
10 changes: 10 additions & 0 deletions lfi-leg/amd64/amd64.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,13 @@ strclean(char* s, size_t n)
}
return sdup;
}

// labels
extern char* funcret;

static inline void
mkfuncret(void)
{
if (args.poc)
mklabel(funcret);
}
13 changes: 9 additions & 4 deletions lfi-leg/amd64/branch.leg
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ CallInd = 'call' 'q'? SEP '*' r:XREG {
bundle_mask(r.val);
mkinsn("callq *%s", r.val);
mkdirective(".bundle_unlock");
mkdirective(bundle_align());
mkfuncret();
} else {
// we use r11 here so that we get consistent instruction sizes, so that the nop
// has the correct size to align the call to the end of the bundle. In theory,
Expand All @@ -32,6 +34,7 @@ CallInd = 'call' 'q'? SEP '*' r:XREG {
mkinsn("callq *%%r11");
mkdirective(".bundle_unlock");
mkdirective(bundle_align());
mkfuncret();
}
rfree(r);
}
Expand Down Expand Up @@ -60,6 +63,7 @@ CallIndMem = 'call' 'q'? SEP '*' a:Addr {
mkinsn("callq *%%r11");
mkdirective(".bundle_unlock");
mkdirective(bundle_align());
mkfuncret();
rfree(a);
}

Expand All @@ -73,21 +77,22 @@ CallIndMemSafe = 'call' 'q'? SEP '*' a:Addr {
mkinsn("callq *%%r11");
mkdirective(".bundle_unlock");
mkdirective(bundle_align());
mkfuncret();
rfree(a);
}

Call = 'call' 'q'? - rest:ITEM {
if (args.poc && args.nopie) {
mkinsn("push $1023f");
mkinsn("push $%sf", funcret);
mkinsn("jmp %s", rest.val);
mkdirective(bundle_align());
mklabel("1023");
mkfuncret();
} else if (args.poc) {
mkinsn("leaq 1023f(%%rip), %%r11");
mkinsn("leaq %sf(%%rip), %%r11", funcret);
mkinsn("pushq %%r11");
mkinsn("jmp %s", rest.val);
mkdirective(bundle_align());
mklabel("1023");
mkfuncret();
} else {
if (args.bundlecall)
mkdirective(bundle_align());
Expand Down
2 changes: 1 addition & 1 deletion lfi-leg/amd64/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ srcs += files(
leg_inputs = [
'parse.leg',
'syscall.leg',
'special.leg',
'decl.leg',
'pextelim.leg',
'tls.leg',
Expand All @@ -19,6 +18,7 @@ leg_addr_inputs = [
'branch.leg',
'loads.leg',
'stores.leg',
'special.leg',
]

foreach l : leg_inputs
Expand Down
22 changes: 10 additions & 12 deletions lfi-leg/amd64/meter.leg
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,27 @@ branchmeter(bool indirect)
{
if (indirect) {
mkinsn("sub $0, %%r12");
// This instruction is written directly as bytes to avoid relying on
// the linker to relax it.
mkinsn(".byte 0x79, 0x01"); // jns next(%rip)
mkinsn("int3");
// next:
// will be replaced with the metering sequence by the post linker
mkinsn("nop"); // jns
mkinsn("nop"); // jns
mkinsn("nop"); // int3
} else {
// leaq 0(%%r12), %%r12 forced to use encoding with a 4-byte immediate
mkinsn(".byte 0x4d, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00");
mkinsn("leaq 512(%%r12), %%r12");
mkinsn("movq %%rcx, %%r11");
mkinsn("mov $0x3f, %%cl");
mkinsn("shrx %%rcx, %%r12, %%rcx");
mkinsn("jrcxz 1024f");
mkinsn("int3");
mklabel("1024");
// will be replaced with the metering sequence by the post linker
mkinsn("nop"); // jrcxz
mkinsn("nop"); // jrcxz
mkinsn("nop"); // int3
mkinsn("movq %%r11, %%rcx");
}
}

static void
timermeter(bool indirect)
{
// leaq 0(%%r12), %%r12 forced to use encoding with a 4-byte immediate
mkinsn(".byte 0x4d, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00");
mkinsn("leaq 512(%%r12), %%r12");
}

static void (*meter)(bool);
Expand Down
4 changes: 1 addition & 3 deletions lfi-leg/amd64/parse.leg
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
Top = Insn* !.

Insn = - Label? (
FnDirective
| BundleDirective
| AlignDirective
BundleDirective
| Directive Comment?
| Comment
| AnyPrefix
Expand Down
12 changes: 7 additions & 5 deletions lfi-leg/amd64/poc.leg
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,30 @@
ctx->idx += yyc != 0; \
result = yyc == 0 ? 0 : (*(buf) = yyc, 1); \
} \

char* funcret = "1023";
%}

Top = CallInd | LeaRip | LeaImmRspRegDisp | LeaRspRegDisp | LeaImmRspReg | LeaRspReg | LeaRsp | MovRsp | AddRsp | MovGot

CallInd = 'call' 'q'? SEP '*' r:XREG {
if (args.nopie) {
mkinsn("push $1023f");
mkinsn("push $%sf", funcret);
mkinsn("jmpq *%s", r.val);
} else if (strcmp(r.val, "%r11") == 0) {
// need %rax as a temporary since %r11 is already in use
mkinsn("pushq %%rax");
mkinsn("leal 1023f(%%rip), %%eax");
mkinsn("leal %sf(%%rip), %%eax", funcret);
// restore %rax and push the return address at the same time
mkinsn("xchg %%rax, (%%rsp)");
mkinsn("jmpq *%s", r.val);
} else {
mkinsn("leal 1023f(%%rip), %%r11d");
mkdirective(".bundle_lock");
mkinsn("leal %sf(%%rip), %%r11d", funcret);
mkinsn("pushq %%r11");
mkdirective(".bundle_unlock");
mkinsn("jmpq *%s", r.val);
}
mkdirective(bundle_align());
mklabel("1023");
rfree(r);
}

Expand Down
17 changes: 16 additions & 1 deletion lfi-leg/amd64/special.leg
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
} \
%}

ModSP = ModLeaSP | ModImmSP | ModRegSP | Leave
ModSP = ModLeaSP | ModAddrSP | ModImmSP | ModRegSP | Leave

AddrBP = (
# imm(...)
Expand Down Expand Up @@ -70,6 +70,21 @@ ModImmSP = m:MODINST i:IMM COMMA '%rsp' - {
rfree(m); rfree(i); free(op);
}

ModAddrSP = m:MODINST a:Addr COMMA '%rsp' - {
char* op = lop(m.val);
mkdirective(".bundle_lock");
if (args.p2size == 0) {
mkinsn("%s %s, %%rsp", m.val, a.unmod);
mkinsn("andq %%r15, %%rsp");
mkinsn("orq %%r14, %%rsp");
} else {
mkinsn("%s %s, %%esp", op, a.unmod);
mkinsn("orq %%r14, %%rsp");
}
mkdirective(".bundle_unlock");
rfree(m); rfree(a); free(op);
}

ModRegSP = m:MODINST r:XREG COMMA '%rsp' - {
char* op = lop(m.val);
mkdirective(".bundle_lock");
Expand Down
6 changes: 0 additions & 6 deletions lfi-leg/test/amd64/branch.s
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,3 @@ orq %r14, %r11
callq *%r11
.bundle_unlock
.p2align 5
------
.type _ZNSt8auto_ptrI9GameStateED2Ev, @function
>>>
.bundle_align_mode 5
.type _ZNSt8auto_ptrI9GameStateED2Ev, @function
.p2align 5
13 changes: 7 additions & 6 deletions lfi-leg/test/amd64/meter.s
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,23 @@ jmpq *%rax
andl $0xffffffe0, %eax
orq %r14, %rax
sub $0, %r12
.byte 0x79, 0x01
int3
nop
nop
nop
jmpq *%rax
.bundle_unlock
------
jmp foo
>>>
.bundle_align_mode 5
.bundle_lock
.byte 0x4d, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00
leaq 512(%r12), %r12
movq %rcx, %r11
mov $0x3f, %cl
shrx %rcx, %r12, %rcx
jrcxz 1024f
int3
1024:
nop
nop
nop
movq %r11, %rcx
jmp foo
.bundle_unlock
8 changes: 4 additions & 4 deletions lfi-leg/test/amd64/meter_timer.s
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ jmp foo
>>>
.bundle_align_mode 5
.bundle_lock
.byte 0x4d, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00
leaq 512(%r12), %r12
jmp foo
.bundle_unlock
------
jz foo
>>>
.bundle_align_mode 5
.bundle_lock
.byte 0x4d, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00
leaq 512(%r12), %r12
jz foo
.bundle_unlock
------
Expand All @@ -20,15 +20,15 @@ jmpq *%rax
.bundle_lock
andl $0xffffffe0, %eax
orq %r14, %rax
.byte 0x4d, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00
leaq 512(%r12), %r12
jmpq *%rax
.bundle_unlock
------
call foo
>>>
.bundle_align_mode 5
.bundle_lock
.byte 0x4d, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00
leaq 512(%r12), %r12
callq foo
.bundle_unlock
.p2align 5
16 changes: 16 additions & 0 deletions lfi-leg/test/amd64/mod.s
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,19 @@ leaq -0x10(%rsp), %rsp
leal -0x10(%esp), %esp
leaq (%rsp, %r14), %rsp
.bundle_unlock
------
mov (%rdi), %rsp
>>>
.bundle_align_mode 5
.bundle_lock
mov %gs:(%edi), %esp
orq %r14, %rsp
.bundle_unlock
------
mov 14(%rdi), %rsp
>>>
.bundle_align_mode 5
.bundle_lock
mov %gs:14(%edi), %esp
orq %r14, %rsp
.bundle_unlock
4 changes: 3 additions & 1 deletion lfi-leg/test/amd64/poc.s
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ callq *%rax
.bundle_lock
andl $0xffffffe0, %eax
orq %r14, %rax
.bundle_lock
leal 1023f(%rip), %r11d
pushq %r11
.bundle_unlock
jmpq *%rax
.bundle_unlock
.p2align 5
1023:
.bundle_unlock
------
leaq x(%rip), %rax
>>>
Expand Down
20 changes: 10 additions & 10 deletions lfi-leg/test/arm64/meter.s
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ bl foo
.bundle_align_mode 4
.p2align 4
.bundle_lock
1000:
sub x23, x23, #0
tbz x23, #63, .+8
tbz x23, #63, 1000b+12
blr x25
bl foo
.bundle_unlock
Expand All @@ -21,8 +22,9 @@ add x18, x21, w0, uxtw
bic x24, x18, 0xf
.p2align 4
.bundle_lock
1000:
sub x23, x23, #0
tbz x23, #63, .+8
tbz x23, #63, 1000b+12
blr x25
blr x24
.bundle_unlock
Expand All @@ -33,8 +35,9 @@ br x0
add x18, x21, w0, uxtw
bic x24, x18, 0xf
.bundle_lock
1000:
sub x23, x23, #0
tbz x23, #63, .+8
tbz x23, #63, 1000b+12
blr x25
br x24
.bundle_unlock
Expand All @@ -49,8 +52,9 @@ ret
.bundle_align_mode 4
bic x24, x30, 0xf
.bundle_lock
1000:
sub x23, x23, #0
tbz x23, #63, .+8
tbz x23, #63, 1000b+12
blr x25
ret x24
.bundle_unlock
Expand All @@ -60,6 +64,7 @@ foo:
>>>
.bundle_align_mode 4
.bundle_lock
1000:
sub x23, x23, #0
b foo
.bundle_unlock
Expand All @@ -71,13 +76,8 @@ foo:
>>>
.bundle_align_mode 4
.bundle_lock
1000:
sub x23, x23, #0
cbnz x0, foo
.bundle_unlock
foo:
------
.p2align 5,,15
>>>
.bundle_align_mode 4
.p2align 5,,15
.p2align 4
1 change: 1 addition & 0 deletions liblfix/arch/amd64/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ SyscallFn syscalls[] = {
[LSYS_readlink] = sysreadlink_,
[LSYS_access] = sysaccess_,
[LSYS_unlink] = sysunlink_,
[LSYS_gettid] = sysignore_,
};

_Static_assert(sizeof(syscalls) / sizeof(SyscallFn) < SYS_max, "syscalls exceed SYS_max");

0 comments on commit f334810

Please sign in to comment.