Created attachment 14962 [details] Скриншот фрагмента кода Динамическая память аллоцируется в lposix.c:354 посредством вызова ф-и 'malloc'. Далее выделенная память не освобождается, это приводит к утечке в lposix.c:360. Прошу обратить внимание на факт того, что эта проблема пофикшена в master-ветке (https://github.com/rpm-software-management/rpm/blob/fa818208abdc68d1bc77c44cc1b5c5a17ea8ffd2/rpmio/lposix.c#L345-L351). Found by Linux Verification Center (https://portal.linuxtesting.ru/) with SVACE. Author E.Bykhanova.
На Sisyphus проверяли ?
Тестирование на версии из Sisyphus не проводилось
answer to https://bugzilla.altlinux.org/48313 [worried-after-failed-exec-in-forked-lua] Спасибо за сообщение и указание на исправление в апстриме! Ясно. Речь про функцию Pexec. Не освобождается память, выделенная под argv. Исправление можно применить при очередном релизе пакета (тривиальный патч cb2ae4bdf2f60876fdc68e3f84938e9c37182fab ) для того, чтобы всё выглядело хорошо и не беспокоило. Но это совсем не критичная утечка памяти: Во-первых, только в случае неуспеха execvp релевантно это замечание. Вот нынешний код из Sisyphus: static int Pexec(lua_State *L) /** exec(path,[args]) */ { const char *path = luaL_checkstring(L, 1); int i,n=lua_gettop(L); char **argv; if (!have_forked) return luaL_error(L, "exec not permitted in this context"); rpmSetCloseOnExec(); argv = malloc((n+1)*sizeof(char*)); if (argv==NULL) return luaL_error(L,"not enough memory"); argv[0] = (char*)path; for (i=1; i<n; i++) argv[i] = (char*)luaL_checkstring(L, i+1); argv[i] = NULL; execvp(path,argv); return pusherror(L, path); } Во-вторых, это может делаться только после форка (в коде выше видна проверка), т.е. как обычно, в процессе, который специально был создан для выполнения внешней программы, которую как раз не удалось запустить. Будет ли после этого этот процесс ещё долго жить, чтобы эта утечка имела какое-то влияние?.. Своё предназначение (в разумной ситуации) этот процесс выполнил и будет уничтожен. Память уже не имеет значения. В-третьих, это не открывает дополнительных возможностей злонамеренно атаковать систему через lua, потому что для этого надо иметь возможность выполнять rpm и выбирать от имени администратора, какие пакеты ставить (с этим lua-кодом), что уже само по себе позволит сделать многое. Где в rpm используется lua, можно ознакомиться, например, на апстримной странице https://rpm.org/docs/4.19.x/manual/lua.html (у нас будет не всё). * Lua scriptlets * Lua macros Lua scriptlets в устанавливаемых пакетах. Lua macros может в ALT и не быть. В любом случае, имея контроль над этими исполняемыми вещами можно и без утечки памяти выполнить более прямую атаку. * * * Для любопытства вот примеры lua scriptlets в ALT: $ git -P -C /people/specbot/public/specs.git/ grep -Fe '<lua>' -A5 sisyphus sisyphus:b/btrfs-progs/btrfs-progs.spec:%pretrans -p <lua> sisyphus:b/btrfs-progs/btrfs-progs.spec-st = posix.stat("/usr/bin/btrfs") sisyphus:b/btrfs-progs/btrfs-progs.spec-if st and st.type == "link" then sisyphus:b/btrfs-progs/btrfs-progs.spec- os.remove("/usr/bin/btrfs") sisyphus:b/btrfs-progs/btrfs-progs.spec-end sisyphus:b/btrfs-progs/btrfs-progs.spec- -- sisyphus:c/ca-trust/ca-trust.spec:%pretrans -p <lua> sisyphus:c/ca-trust/ca-trust.spec--- Blocklist symlinks become blacklist directories. sisyphus:c/ca-trust/ca-trust.spec--- And blacklist directories become blocklist symlinks. sisyphus:c/ca-trust/ca-trust.spec-paths = { "%_datadir/pki/ca-trust-source/", "%catrustdir/source/" } sisyphus:c/ca-trust/ca-trust.spec-name_new = "blocklist" sisyphus:c/ca-trust/ca-trust.spec-name_old = "blacklist" -- sisyphus:e/example-pretrans-dir-to-symlink/dir-to-symlink.spec:Note that '%%pretrans' scriptlets MUST be written in Lua and thus use -p <lua> sisyphus:e/example-pretrans-dir-to-symlink/dir-to-symlink.spec-in order to function during initial system installation when no shell has yet sisyphus:e/example-pretrans-dir-to-symlink/dir-to-symlink.spec-been installed. sisyphus:e/example-pretrans-dir-to-symlink/dir-to-symlink.spec- sisyphus:e/example-pretrans-dir-to-symlink/dir-to-symlink.spec-%build sisyphus:e/example-pretrans-dir-to-symlink/dir-to-symlink.spec-date > file.txt -- sisyphus:e/example-pretrans-dir-to-symlink/dir-to-symlink.spec:%pretrans -p <lua> sisyphus:e/example-pretrans-dir-to-symlink/dir-to-symlink.spec--- Define the path to directory being replaced below. sisyphus:e/example-pretrans-dir-to-symlink/dir-to-symlink.spec--- DO NOT add a trailing slash at the end. sisyphus:e/example-pretrans-dir-to-symlink/dir-to-symlink.spec-path = "%_libexecdir/%name/b" sisyphus:e/example-pretrans-dir-to-symlink/dir-to-symlink.spec-st = posix.stat(path) sisyphus:e/example-pretrans-dir-to-symlink/dir-to-symlink.spec-if st and st.type == "directory" then -- sisyphus:e/example-pretrans-symlink-to-dir/symlink-to-dir.spec:Note that '%%pretrans' scriptlets MUST be written in Lua and thus use -p <lua> sisyphus:e/example-pretrans-symlink-to-dir/symlink-to-dir.spec-in order to function during initial system installation when no shell has yet sisyphus:e/example-pretrans-symlink-to-dir/symlink-to-dir.spec-been installed. sisyphus:e/example-pretrans-symlink-to-dir/symlink-to-dir.spec- sisyphus:e/example-pretrans-symlink-to-dir/symlink-to-dir.spec-%build sisyphus:e/example-pretrans-symlink-to-dir/symlink-to-dir.spec-date > file.txt -- sisyphus:e/example-pretrans-symlink-to-dir/symlink-to-dir.spec:%pretrans -p <lua> sisyphus:e/example-pretrans-symlink-to-dir/symlink-to-dir.spec--- Define the path to the symlink being replaced below. sisyphus:e/example-pretrans-symlink-to-dir/symlink-to-dir.spec-path = "%_libexecdir/%name/symlinked" sisyphus:e/example-pretrans-symlink-to-dir/symlink-to-dir.spec-st = posix.stat(path) sisyphus:e/example-pretrans-symlink-to-dir/symlink-to-dir.spec-if st and st.type == "link" then sisyphus:e/example-pretrans-symlink-to-dir/symlink-to-dir.spec- os.remove(path) -- sisyphus:f/filesystem/filesystem.spec:%pretrans -p <lua> sisyphus:f/filesystem/filesystem.spec-migrate = false sisyphus:f/filesystem/filesystem.spec-if posix.stat("/usr") then sisyphus:f/filesystem/filesystem.spec- -- See if we need to migrate to merged-usr. sisyphus:f/filesystem/filesystem.spec- for i, d in pairs({ sisyphus:f/filesystem/filesystem.spec-"/bin", -- sisyphus:f/firmware-alsa-sof/firmware-alsa-sof.spec:%pretrans -p <lua> sisyphus:f/firmware-alsa-sof/firmware-alsa-sof.spec-path = "%{_firmwarepath}/intel/sof-tplg" sisyphus:f/firmware-alsa-sof/firmware-alsa-sof.spec-st = posix.stat(path) sisyphus:f/firmware-alsa-sof/firmware-alsa-sof.spec-if st and st.type == "link" then sisyphus:f/firmware-alsa-sof/firmware-alsa-sof.spec- os.remove(path) sisyphus:f/firmware-alsa-sof/firmware-alsa-sof.spec-end -- sisyphus:f/firmware-linux/linux-firmware.spec:%pretrans -p <lua> sisyphus:f/firmware-linux/linux-firmware.spec-paths = { sisyphus:f/firmware-linux/linux-firmware.spec- "/lib/firmware/nvidia/ad103", sisyphus:f/firmware-linux/linux-firmware.spec- "/lib/firmware/nvidia/ad104", sisyphus:f/firmware-linux/linux-firmware.spec- "/lib/firmware/nvidia/ad106", sisyphus:f/firmware-linux/linux-firmware.spec- "/lib/firmware/nvidia/ad107" -- sisyphus:g/gajim/gajim.spec:%pretrans -p <lua> sisyphus:g/gajim/gajim.spec--- see http://git.altlinux.org/gears/e/example-pretrans-dir-to-symlink.git sisyphus:g/gajim/gajim.spec--- Define the path to directory being replaced below. sisyphus:g/gajim/gajim.spec--- DO NOT add a trailing slash at the end. sisyphus:g/gajim/gajim.spec-path = "%python3_sitelibdir/%name/data" sisyphus:g/gajim/gajim.spec-st = posix.stat(path) -- sisyphus:t/tuxguitar/tuxguitar.spec:%pretrans -p <lua> sisyphus:t/tuxguitar/tuxguitar.spec-path = "%{_iconsdir}/hicolor/96x96/apps/tuxguitar.png" sisyphus:t/tuxguitar/tuxguitar.spec-st = posix.stat(path) sisyphus:t/tuxguitar/tuxguitar.spec-if st and st.type == "directory" then sisyphus:t/tuxguitar/tuxguitar.spec- if posix.stat(path .. "/icon.png") then sisyphus:t/tuxguitar/tuxguitar.spec- os.remove(path .. "/icon.png") -- sisyphus:u/usrmerge/usrmerge.spec:%pre ensure -p <lua> sisyphus:u/usrmerge/usrmerge.spec-hier_convert_prog = "%_prefix/libexec/usrmerge/hier-convert" sisyphus:u/usrmerge/usrmerge.spec--- Ensure log messages are line-buffered. sisyphus:u/usrmerge/usrmerge.spec-os.execute("printf '%%s\n' '%name-ensure-%EVR: Starting usrmerge-hier-convert...'") sisyphus:u/usrmerge/usrmerge.spec-assert(os.execute(hier_convert_prog)) sisyphus:u/usrmerge/usrmerge.spec-