Re: Segfault with 32-bit luajit, ffi and some C code

  • From: Mike Pall <mike-1507@xxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Wed, 1 Jul 2015 06:53:50 +0200

Thiago Padilha wrote:

Now the strangest part: If I change the last line of "segfault.lua" from
`assert(cmp('long') == 0)` to `assert(cmp('lon') == 0)`(or simply change
the length of the string being compared to a number different than 4) the
crash doesn't happen!

Here's your buffer overrun, writing the NUL terminator:

local c_char = ffi.typeof('char[?]')
local len = string.len(str)
local buf = c_char(len, str)

Read upon initializers in the docs:

"Byte arrays may also be initialized with a Lua string. This
copies the whole string plus a terminating zero-byte. The copy stops
early only if the array has a known, fixed size."

A VLA does not have a fixed size.

BTW#1: None of that buffer copying is necessary. Fix the
declaration of rbuffer_write to take a const char * and directly
pass the string.

BTW#2: Umm, string.len()? The '#' operator has been there for years.

BTW#3: If you want a somewhat efficient implementation of the read
function, then use rbuffer_read_ptr with judicious use of a second
call. Allocate the size_t[1] as an upvalue.

--Mike

Other related posts: