The following fragment of code, entered into a Lua 5.1.x (<= 5.1.3) interpreter, can cause the interpreter to crash/segfault:

loadstring(
  string.dump(function()return;end)
  :gsub("\30%z\128",'"\0\0',1)
)()

Note that this only works on standard builds of Lua where virtual machine instructions are expressed in 32 bit little endian integers. So, for example, you can make Company of Heroes crash by entering equivalent code into its console. Read on for a description of why this causes a crash.


Edit: Another related, albeit different crash-causing line: (Which makes it two bugs I've found)

loadstring(
  string.dump(function(...)a,b,c,d=...;a=1;end)
  :gsub("e%z\128\2.....",'\2@\128\0"\0\128\0$')
)()

To understand why this causes a crash, it is important to know:

By combining these three facts, if the penultimate instruction in the array is a special SETLIST, and the final instruction is a RETURN, then the code will pass through the loading checks, and then cause the VM to move beyond the end of the instruction array. The code at the start of this post creates a function comprised to two RETURN instructions (function()return;end), converts it to a string (string.dump), replaces the first RETURN with a SETLIST (gsub("\30%z\128",'"\0\0',1)), then converts the string back into a function (loadstring) and executes it (()). The VM is now executing the random instructions which are after the end of the instruction array, which is very likely to cause a segfault/crash, or in the best-case scenario, an obscure runtime error.

For the second example, it is important to know (on top of the previous knowledge):

The code creates a function with 4 instructions in it (function(...)a,b,c,d=...;a=1;end), converts it to a string (string.dump), replaces the first three instructions with LOADBOOL, SETLIST and CLOSURE instructions (gsub("e%z\128\2.....",'\2@\128\0"\0\128\0$')) then converts the string back into a function (loadstring) and executes it (()). The interpreter executes the CLOSURE instruction, which leads to a segfault because it refers to a non-existent function prototype. The checks that are done when a precompiled chunk are loaded should have caught this and never allowed it to happen, but the SETLIST caused the CLOSURE to be interpreted as a non-instruction. The actual thing that wasn't caught was the LOADBOOL jumping over the SETLIST, causing the CLOSURE to actually be interpreted as an instruction. The other cases of an instruction being skipped have to be followed by a JUMP, so are not useful for this attack, but that check isn't made for LOADBOOL. The CLOSURE could have been one of several other instructions whose array indices are sanity checked at compile-time rather than runtime, but it seemed to give more consistent segfaults, so I went with it.