[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Double free leading to segmentation fault
- From: Sören Tempel <soeren@...>
- Date: Thu, 14 Apr 2022 23:05:26 +0200
Hi,
I am a contributor to the Alpine Linux distribution. We recently
encountered a double free which leads to a segmentation fault while
building lsyncd with lua 5.4.4 [1].
To me, it looks like the lineinfo memory is freed twice. Once via
combine() and once via close_state(). The valgrind output looks
as follows:
==29903== Invalid free() / delete / delete[] / realloc()
==29903== at 0x48A4B0D: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==29903== by 0x11E5D2: l_alloc (lauxlib.c:1014)
==29903== by 0x112F51: luaM_free_ (lmem.c:135)
==29903== by 0x11111B: luaF_freeproto (lfunc.c:271)
==29903== by 0x112ABB: deletelist (lgc.c:1494)
==29903== by 0x112ABB: luaC_freeallobjects (lgc.c:1511)
==29903== by 0x116D54: close_state (lstate.c:276)
==29903== by 0x10B549: main (luac.c:210)
==29903== Address 0x48ec220 is 0 bytes inside a block of size 10 free'd
==29903== at 0x48A4B0D: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==29903== by 0x11E5D2: l_alloc (lauxlib.c:1014)
==29903== by 0x112F51: luaM_free_ (lmem.c:135)
==29903== by 0x10C60C: combine (luac.c:158)
==29903== by 0x10C60C: pmain (luac.c:183)
==29903== by 0x10FF38: precallC (ldo.c:506)
==29903== by 0x11020C: luaD_precall (ldo.c:572)
==29903== by 0x110340: ccall (ldo.c:607)
==29903== by 0x10F7CA: luaD_rawrunprotected (ldo.c:144)
==29903== by 0x110668: luaD_pcall (ldo.c:926)
==29903== by 0x10DB2F: lua_pcallk (lapi.c:1067)
==29903== by 0x10B528: main (luac.c:209)
==29903== Block was alloc'd at
==29903== at 0x48A6FC9: realloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==29903== by 0x112F7E: luaM_realloc_ (lmem.c:166)
==29903== by 0x112FC5: luaM_saferealloc_ (lmem.c:180)
==29903== by 0x113074: luaM_shrinkvector_ (lmem.c:116)
==29903== by 0x114B02: close_func (lparser.c:764)
==29903== by 0x116B1B: mainfunc (lparser.c:1937)
==29903== by 0x116B1B: luaY_parser (lparser.c:1959)
==29903== by 0x10F718: f_parser (ldo.c:971)
==29903== by 0x10F7CA: luaD_rawrunprotected (ldo.c:144)
==29903== by 0x110668: luaD_pcall (ldo.c:926)
==29903== by 0x11074B: luaD_protectedparser (ldo.c:988)
==29903== by 0x10DC13: lua_load (lapi.c:1097)
==29903== by 0x10C5B1: combine (luac.c:151)
==29903== by 0x10C5B1: pmain (luac.c:183)
I am not familiar with the lua code base, but a simple fix would be to
have combine() assign NULL to f->lineinfo to ensure that it is not freed
again later on:
diff -upr lua-5.4.4.orig/src/luac.c lua-5.4.4/src/luac.c
--- lua5.4.4.orig/src/luac.c 2022-04-14 20:57:01.927447850 +0200
+++ lua-5.4.4/src/luac.c 2022-04-14 20:57:35.260900910 +0200
@@ -156,6 +156,7 @@ static const Proto* combine(lua_State* L
if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0;
}
luaM_freearray(L,f->lineinfo,f->sizelineinfo);
+ f->lineinfo=NULL;
f->sizelineinfo=0;
return f;
}
Would be nice if this could get this fixed properly upstream.
Greetings,
Sören
[1]: https://gitlab.alpinelinux.org/alpine/aports/-/issues/13694