Skip to content

Instantly share code, notes, and snippets.

@agentzh
Last active October 2, 2017 19:56
Show Gist options
  • Save agentzh/60b7b3ae8db24934132cbf3978ae5525 to your computer and use it in GitHub Desktop.
Save agentzh/60b7b3ae8db24934132cbf3978ae5525 to your computer and use it in GitHub Desktop.
local ffi = require 'ffi'
local SH = ffi.load("./set-header.so")
ffi.cdef[[
int my_set_header(uintptr_t r,
const unsigned char *key, const unsigned char *value);
]]
getfenv(0).req = ffi.new("uintptr_t")
local function set_header(name, value)
local r = getfenv(0).req
value = tostring(value)
SH.my_set_header(r, name, value)
end
for i = 1, 500 do
set_header("foo", i)
end
#include <stdint.h>
int
my_set_header(uintptr_t r, const unsigned char *key, const unsigned char *value)
{
return 0;
}
$ gcc --version
gcc (GCC) 6.4.1 20170727 (Red Hat 6.4.1-1)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ cat /etc/redhat-release
Fedora release 25 (Twenty Five)
$ uname -a
Linux fedora64 4.11.8-100.fc24.x86_64 #1 SMP Thu Jun 29 18:05:45 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
# Build the latest LuaJIT v2.1 with GC64 mode:
$ cd ~/git/luajit-2.0
$ git checkout v2.1
Already on 'v2.1'
Your branch is up-to-date with 'origin/v2.1'.
$ git show
commit b4ed3219a1a98dd9fe7d1e3eeea3b82f5a780948
Author: Mike Pall <mike>
Date: Mon Oct 2 09:22:46 2017 +0200
LJ_GC64: Fix ir_khash for non-string GCobj.
Contributed by Peter Cawley.
diff --git a/src/lj_asm.c b/src/lj_asm.c
index bed2268efe..d961927bde 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -1017,7 +1017,11 @@ static uint32_t ir_khash(IRIns *ir)
} else {
lua_assert(irt_isgcv(ir->t));
lo = u32ptr(ir_kgc(ir));
+#if LJ_GC64
+ hi = (uint32_t)(u64ptr(ir_kgc(ir)) >> 32) | (irt_toitype(ir->t) << 15);
+#else
hi = lo + HASH_BIAS;
+#endif
}
return hashrot(lo, hi);
}
$ PREFIX=/opt/luajit21dbg \
sudo rm -rf $PREFIX && \
make Q= CC=gcc PREFIX=$PREFIX CCDEBUG=-g -j8 XCFLAGS='-DLUAJIT_ENABLE_GC64' && \
sudo make install PREFIX=$PREFIX
$ cd ~/test/ # copy the fake-req.lua and set-header.c files above to this directory
$ gcc -shared -Wall -fpic set-header.c -o set-header.so
$ /opt/luajit21dbg/bin/luajit-2.1.0-beta3 fake-req.lua
Segmentation fault (core dumped)
$ gdb --args /opt/luajit21dbg/bin/luajit-2.1.0-beta3 -jdump fake-req.lua
GNU gdb (GDB) Fedora 7.12.1-48.fc25
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /opt/luajit21dbg/bin/luajit-2.1.0-beta3...done.
(gdb) r
Starting program: /opt/luajit21dbg/bin/luajit-2.1.0-beta3 -jdump fake-req.lua
---- TRACE 1 start fake-req.lua:18
0022 MOV 7 2
0023 KSTR 9 11 ; "foo"
0024 MOV 10 6
0025 CALL 7 1 3
0000 . FUNCF 8 ; fake-req.lua:12
0001 . GGET 2 0 ; "getfenv"
0002 . KSHORT 4 0
0003 . CALL 2 2 2
0000 . . FUNCC ; getfenv
0004 . TGETS 2 2 1 ; "req"
0005 . GGET 3 2 ; "tostring"
0006 . MOV 5 1
0007 . CALL 3 2 2
0000 . . FUNCC ; tostring
0008 . MOV 1 3
0009 . UGET 3 0 ; SH
0010 . TGETS 3 3 3 ; "my_set_header"
0000 . . . FUNCC ; ffi.clib.__index
0011 . MOV 5 2
0012 . MOV 6 0
0013 . MOV 7 1
0014 . CALL 3 1 4
0000 . . FUNCC ; ffi.meta.__call
0015 . RET0 0 1
0026 FORL 3 => 0022
---- TRACE 1 IR
0001 int SLOAD #5 CI
0002 > fun SLOAD #4 T
0003 > fun EQ 0002 fake-req.lua:12
0004 tab FLOAD fake-req.lua:12 func.env
0005 int FLOAD 0004 tab.hmask
0006 > int EQ 0005 +63
0007 p64 FLOAD 0004 tab.node
0008 > p64 HREFK 0007 "getfenv" @62
0009 > fun HLOAD 0008
0010 > fun EQ 0009 getfenv
0011 thr LREF
0012 tab FLOAD 0011 thread.env
0013 int FLOAD 0012 tab.hmask
0014 > int EQ 0013 +63
0015 p64 FLOAD 0012 tab.node
0016 > p64 HREFK 0015 "req" @35
0017 > cdt HLOAD 0016
0018 > p64 HREFK 0007 "tostring" @6
0019 > fun HLOAD 0018
0020 > fun EQ 0019 tostring
0021 str TOSTR 0001 INT
0022 > p64 UREFO fake-req.lua:12 #0
0023 p64 ADD 0022 -8
0024 > p64 EQ 0023 0000
0025 > udt SLOAD #3 T
0026 > p64 EQ 0025 [0x7ffff7fb8e40]
0027 u16 FLOAD 0017 cdata.ctypeid
0028 > int EQ 0027 +12
0029 u64 FLOAD 0017 cdata.int64
0030 p64 ADD 0021 +24
0033 int CALLXS [0x7ffff70eb650](0029 [0x7ffff7fb9eb8] 0030)
0034 + int ADD 0001 +1
0035 > int LE 0034 +500
0036 ------ LOOP ------------
0037 str TOSTR 0034 INT
0038 > p64 UREFO fake-req.lua:12 #0
0039 p64 ADD 0038 -8
0040 > p64 EQ 0039 0000
0041 p64 ADD 0037 +24
0043 int CALLXS [0x7ffff70eb650](0029 [0x7ffff7fb9eb8] 0041)
0044 + int ADD 0034 +1
0045 > int LE 0044 +500
0046 int PHI 0034 0044
---- TRACE 1 mcode 576
2a50fdb7 add rsp, -0x10
2a50fdbb mov dword [r14-0xed0], 0x1
2a50fdc6 lea rbx, [r14-0xeebcd8]
2a50fdcd mov rdi, [r14-0xf30]
2a50fdd4 cmp rdi, [r14-0xf28]
2a50fddb jb 0x2a50fdf6
2a50fddd mov esi, 0x1
2a50fde2 lea rdi, [r14-0xf50]
2a50fde9 call 0x00423e40 ->lj_gc_step_jit
2a50fdee test eax, eax
2a50fdf0 jnz 0x2a500010 ->0
2a50fdf6 mov rdi, [r14-0xdf8]
2a50fdfd lea rsi, [r14+0x28b8]
2a50fe04 mov rdx, [r14-0xdf0]
2a50fe0b lea rcx, [r14+0x2bc8]
2a50fe12 lea rax, [r14+0xa530]
2a50fe19 cvttsd2si ebp, [rdx+0x18]
2a50fe1e rorx rdx, [rdx+0x10], 0x2f
2a50fe25 cmp dx, -0x09
2a50fe29 jnz 0x2a500010 ->0
2a50fe2f shr rdx, 0x11
2a50fe33 cmp rdx, rax
2a50fe36 jnz 0x2a500010 ->0
2a50fe3c mov rax, [rax+0x10]
2a50fe40 cmp dword [rax+0x34], +0x3f
2a50fe44 jnz 0x2a500010 ->0
2a50fe4a mov rax, [rax+0x28]
2a50fe4e mov rdx, 0xfffdfffff7fd9c18
2a50fe58 cmp rdx, [rax+0x5d8]
2a50fe5f jnz 0x2a500010 ->0
2a50fe65 rorx rdx, [rax+0x5d0], 0x2f
2a50fe6f cmp dx, -0x09
2a50fe73 jnz 0x2a500010 ->0
2a50fe79 shr rdx, 0x11
2a50fe7d cmp rdx, rsi
2a50fe80 jnz 0x2a500010 ->0
2a50fe86 mov edx, edi
2a50fe88 mov rdx, [rdx+0x48]
2a50fe8c cmp dword [rdx+0x34], +0x3f
2a50fe90 jnz 0x2a500010 ->0
2a50fe96 mov rdx, [rdx+0x28]
2a50fe9a mov rsi, 0xfffdfffff7fb9ec8
2a50fea4 cmp rsi, [rdx+0x350]
2a50feab jnz 0x2a500010 ->0
2a50feb1 rorx r12, [rdx+0x348], 0x2f
2a50febb cmp r12w, -0x0b
2a50fec0 jnz 0x2a500010 ->0
2a50fec6 shr r12, 0x11
2a50feca mov rsi, 0xfffdfffff7fd9f28
2a50fed4 cmp rsi, [rax+0x98]
2a50fedb jnz 0x2a500010 ->0
2a50fee1 rorx rax, [rax+0x90], 0x2f
2a50feeb cmp ax, -0x09
2a50feef jnz 0x2a500010 ->0
2a50fef5 shr rax, 0x11
2a50fef9 cmp rax, rcx
2a50fefc jnz 0x2a500010 ->0
2a50ff02 mov esi, ebp
2a50ff04 call 0x0040a5f0 ->lj_strfmt_int
2a50ff09 mov rdx, [r14-0xdf0]
2a50ff10 lea rcx, [r14-0x1e4e8]
2a50ff17 mov rsi, [r14+0x8d50]
2a50ff1e add rsi, -0x08
2a50ff22 cmp rsi, rdx
2a50ff25 jnz 0x2a500010 ->0
2a50ff2b rorx r13, [rdx+0x8], 0x2f
2a50ff32 cmp r13w, -0x0d
2a50ff37 jnz 0x2a500010 ->0
2a50ff3d shr r13, 0x11
2a50ff41 cmp r13, rcx
2a50ff44 jnz 0x2a500010 ->0
2a50ff4a cmp word [r12+0xa], +0x0c
2a50ff51 jnz 0x2a500010 ->0
2a50ff57 mov rdi, [r12+0x10]
2a50ff5c mov [rsp+0x8], rdi
2a50ff61 mov rdx, rax
2a50ff64 add rdx, +0x18
2a50ff68 lea rsi, [r14-0x1d470]
2a50ff6f call rbx
2a50ff71 add ebp, +0x01
2a50ff74 cmp ebp, 0x1f4
2a50ff7a jg 0x2a500014 ->1
->LOOP:
2a50ff80 mov rdi, [r14-0xf30]
2a50ff87 cmp rdi, [r14-0xf28]
2a50ff8e jb 0x2a50ffa9
2a50ff90 mov esi, 0x1
2a50ff95 lea rdi, [r14-0xf50]
2a50ff9c call 0x00423e40 ->lj_gc_step_jit
2a50ffa1 test eax, eax
2a50ffa3 jnz 0x2a500018 ->2
2a50ffa9 mov rdi, [r14-0xdf8]
2a50ffb0 mov esi, ebp
2a50ffb2 call 0x0040a5f0 ->lj_strfmt_int
2a50ffb7 mov rdi, [rsp+0x8]
2a50ffbc mov rdx, [r14-0xdf0]
2a50ffc3 mov r15, [r14+0x8d50]
2a50ffca add r15, -0x08
2a50ffce cmp r15, rdx
2a50ffd1 jnz 0x2a500018 ->2
2a50ffd7 mov rdx, rax
2a50ffda add rdx, +0x18
2a50ffde lea rsi, [r14-0x1d470]
2a50ffe5 call rbx
2a50ffe7 add ebp, +0x01
2a50ffea cmp ebp, 0x1f4
2a50fff0 jle 0x2a50ff80 ->LOOP
2a50fff2 jmp 0x2a50001c ->3
---- TRACE 1 stop -> loop
Program received signal SIGSEGV, Segmentation fault.
0x000000002a50fe88 in ?? ()
(gdb) display/i $pc
1: x/i $pc
=> 0x2a50fe88: mov rdx,QWORD PTR [rdx+0x48]
(gdb) info reg
rax 0x7ffff7fd7d78 140737353973112
rbx 0x7ffff70eb650 140737338324560
rcx 0x7ffff7fd9ef0 140737353981680
rdx 0xf7fd6378 4160578424
rsi 0x7ffff7fd9be0 140737353980896
rdi 0x7ffff7fd6378 140737353966456
rbp 0x3a 0x3a
rsp 0x7fffffffd420 0x7fffffffd420
r8 0x7ffff7fd7328 140737353970472
r9 0x10 16
r10 0x10 16
r11 0x420377 4326263
r12 0x0 0
r13 0x0 0
r14 0x7ffff7fd7328 140737353970472
r15 0x7ffff7fbe510 140737353868560
rip 0x2a50fe88 0x2a50fe88
eflags 0x10246 [ PF ZF IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment