Bithack / principia

Open source physics-based sandbox game.
https://principia-web.se
Other
258 stars 25 forks source link

(use-after-free) Crash when trying to use an exploded bomb/bullet entity in lua on android #83

Open griffi-gh opened 1 year ago

griffi-gh commented 1 year ago

Weird but this doesn't happen on Windows, where the invalid object reference just keeps "working" (maybe a use-after-free situation or just an invalid object reference?) I was able to reproduce this like this:

local e
function init(is_sandbox)
    e = world:query(-999, -999, 999, 999, 1)
end
function step(count)
    for i,v in ipairs(e) do
        game:message(i)
        v:get_position()
    end
end

This issue only happens if e is a top-level local, and the object safely gets removed if e is a global

griffi-gh commented 1 year ago

Comment the first line and the message changes from 4 to 3 when the bomb explodes.
Keeping it as-is causes the number to stay at 4, accessing broken references causes a crash on android and on windows get_position returns 0

griffi-gh commented 1 year ago

(maybe title needs to be updated)

griffi-gh commented 1 year ago

Discovered this accidentaly in this level: https://principia-web.se/level/676

griffi-gh commented 1 year ago

Another more straight forward example:

local ref
function init()
  ref = world:get_entity_by_id(2)
end
function step(count)
  if count > 200 then
    ref:highlight()
  end
end

After the bomb explodes on windows place where it was before the explosion is highlighted, and on android this causes a lua error and not a crash... wtf

griffi-gh commented 1 year ago
local ref
function init()
  ref = world:get_entity_by_id(2)
end
function step(count)
  if count == 3 then
    game:message(ref:get_name())
  end
  if count == 240 then
    game:message(ref:get_name())
  end
end

This on frame 3 prints "Bomb" and on frame 240 (after explosion) "Toggle axis rotation"?????

griffi-gh commented 1 year ago

calling :set_color() on ref crashes on windows

griffi-gh commented 1 year ago

After looking at the escript source I think this is actually use-after-free? Game tries to clean up objects from the stack and globals but fails in this case???

griffi-gh commented 6 months ago

(way overdue) correction: any form of disowning triggers this too, for example calling absorb