[Dev-luatex] Lua states and \dump

Jonathan Sauer Jonathan.Sauer at silverstroke.com
Tue Sep 25 09:23:08 CEST 2007


Hello,

> > Thanks for your answer! After reading up on bytecode registers in
the 
> > manual, one question is left, though:
> > 
> > How many of them are there? The usual 65536?
> 
> more -)

Well, I experimented a bit and am now a lot wiser. Also, I have
confirmation on what I thought all along: My computer's internal
harddisk is much too slow:

How to measure the performance of virtual memory:

\directlua0{lua.bytecode[100000000] = function() end}


On a more serious matter, though, there is a buffer overflow in
llualib.c, function set_bytecode: If `sizeof(bytecode)*(k+1)' is
larger than UINT_MAX, a numeric overflow occurs and not enough memory
is allocated in line 162. When initializing the newly allocated
bytecode registers afterwards, random memory is overwritten.

Example (without exploit, of course):

Register number = 1000000000:

$ luatex
This is luaTeX, Version 3.141592-beta-0.11.2-2007091918 (Web2C 7.5.6)
**\directlua0{lua.setbytecode(1000000000,function() end)}

luatex(515) malloc: *** vm_allocate(size=3115102208) failed (error
code=3)
luatex(515) malloc: *** error: can't allocate region
luatex(515) malloc: *** set a breakpoint in szone_error to debug
fatal: memory exhausted (xmalloc of 3115098128 bytes).

(note that `3115098128' is already the result of an overflow. On my
machine, sizeof(bytecode) is 16, so 16000000016[1] bytes should have
been
allocated [or tried to]. 16000000016 mod 2^32 = 3115098128)


Register number = 2000000000:

$ luatex
This is luaTeX, Version 3.141592-beta-0.11.2-2007091918 (Web2C 7.5.6)
**\directlua0{lua.setbytecode(2000000000,function() end)}
Killed

(I killed the process in the latter experiment, as it still consumed
too much memory [about 1.9GB]. But: Even though the memory
requirements have been higher than in the first example, in this case
the allocation did not fail, as the overflow created a smaller
allocation, `only' 1935228944 bytes)


Register number = 3000000000:

$ luatex
This is luaTeX, Version 3.141592-beta-0.11.2-2007091918 (Web2C 7.5.6)
**\directlua0{lua.setbytecode(3000000000,function() end)}
luatex(528) malloc: ***  Deallocation of a pointer not malloced:
0x1b4d0c0; This could be a double free(), or free() called with the
middle of an allocated block; Try setting environment variable
MallocHelp to see tools to help debug
^^@^^@^^@^^@^^@^^@^^@^^@^^@^^@^^@^^@^^@^^@e
on^^@^^@^^@^^@^^@^^@^^@^^@^^@^^@^^@
^^@^^@^^@^^@^^@^^@^^@^^@
Ple^^@^^@^^@^^@^^@^^@^^@^^@^^@^^@^^@^^@ther^^@^^@^^@^^@^^@^^@^^@ript^^@^
^@^^@
^^@^^@^^@^^@^^@^^@^^@^^@^^@

(followed by a more-or-less crash [strangely, LuaTeX was still active
afterwards[3]] due to accessing invalid memory. In this case, only
755359760 bytes were allocated, even though 48000000016 were required.
The ^^@ demonstrate how memory has been overwritten with zeros)


IMO it would be sensible to limit the number of bytecode registers to
UINT_MAX/sizeof(bytecode) or -- to be platform-independent in the
light of 64 bit processors[2] -- (2^32-1)/sizeof(bytecode).


[1] LuaTeX always allocates memory for one additional register

[2] Where UINT_MAX might well be 2^64-1

[3] I think, this is the result of the sig-handler LuaTeX installs
which displays an error message. But it seems that this message has
been overwritten as well.

Except for `e on', `Ple', `ther' and `ript' -- let's hope LuaTeX does
not pull an Event Horizon (from the movie) here. But I think this is
just
because bytecode.alloc is not initialized, so the last four bytes of
every 16 byte block of LuaTeX's memory are not overwritten.


Of course, all of this is void, if the current bytecode register
implementation is only temporary.


Jonathan



More information about the dev-luatex mailing list