From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 451D627280 for ; Thu, 22 Aug 2019 21:58:02 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 84FISrRV2D3g for ; Thu, 22 Aug 2019 21:58:02 -0400 (EDT) Received: from smtp61.i.mail.ru (smtp61.i.mail.ru [217.69.128.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id 91BFC27267 for ; Thu, 22 Aug 2019 21:58:01 -0400 (EDT) From: Alexander Turenko Subject: [tarantool-patches] [PATCH] lua: pwd: fix passwd and group traversal Date: Fri, 23 Aug 2019 04:57:34 +0300 Message-Id: <5545c38a61fe1867743a75b6bb4767b8e87c629e.1566524401.git.alexander.turenko@tarantool.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-Help: List-Unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-Subscribe: List-Owner: List-post: List-Archive: To: Vladislav Shpilevoy Cc: Alexander Turenko , tarantool-patches@freelists.org CentOS 6 and FreeBSD 12 implementations of getpwuid() rewind setpwent()-{getpwent()}-endpwent() loop to a start that leads to a hang during pwd.getpwall() invoke. The same is true for a getgrgid() call during setgrent()-{getgrent()}-endgrent() loop. The commit modifies pwd module to avoid getpwuid() calls during passwd database traversal and to avoid getgrgid() calls when traversing groups. The commit also fixes the important regression on CentOS 6 after f5d8331e833d6a29dc7a869e681e03fb8e03a5f8 ('lua: workaround pwd.getpwall() issue on Fedora 29'): tarantool hungs during startup due to added getpwall() call. This made tarantool unusable on CentOS 6 at all. Aside of that the commit fixes another pwd.getgrall() problem: the function gaves password entries instead of group entries. Fixes #4428. Fixes #4447. Part of #4271. --- The primary reason of this commit is to overcome a startup hang on CentOS 6. https://github.com/tarantool/tarantool/issues/4428 https://github.com/tarantool/tarantool/issues/4447 https://github.com/tarantool/tarantool/issues/4271 https://github.com/tarantool/tarantool/tree/Totktonada/gh-4447-fix-centos-6-startup-fail-full-ci Waiting for CI: https://gitlab.com/tarantool/tarantool/pipelines/77906160 I manually verified that tarantool starts on CentOS 6 after the change. Also verified that the module can be used now on FreeBSD 12.0. I understood that the commit formally changes a behaviour that can be visible for a user: it allows to pass cdata to pwd.getgr() and to pass cdata to pwd.getgr(). It is unlikely that one will want to use it or will find this ability by an occasion. Maybe only with pwd.getpw(1LL) or so, but luajit will report an error in the case. My intention was to keep the commit short and avoid refactoring of the module code. It would be good to refactor it in a future: split cdata / cdata acquiring from transformation of them into tables. I tried to do so, but it moves much code around the module, so I skipped it. Hope it should not be done in the scope of the issue with CentOS 6. src/lua/pwd.lua | 15 +++++---------- test/app-tap/pwd.skipcond | 8 -------- 2 files changed, 5 insertions(+), 18 deletions(-) delete mode 100644 test/app-tap/pwd.skipcond diff --git a/src/lua/pwd.lua b/src/lua/pwd.lua index b6de1562f..ab0229a72 100644 --- a/src/lua/pwd.lua +++ b/src/lua/pwd.lua @@ -112,7 +112,7 @@ local function getgr(gid) if gid == nil then gid = tonumber(ffi.C.getgid()) end - local gr = _getgr(gid) + local gr = type(gid) == 'cdata' and gid or _getgr(gid) if gr == nil then if errno() ~= 0 then error(pwgr_errstr:format('gr', errno(), errno.strerror())) @@ -141,7 +141,7 @@ local function getpw(uid) if uid == nil then uid = tonumber(ffi.C.getuid()) end - local pw = _getpw(uid) + local pw = type(uid) == 'cdata' and uid or _getpw(uid) if pw == nil then if errno() ~= 0 then error(pwgr_errstr:format('pw', errno(), errno.strerror())) @@ -170,7 +170,7 @@ local function getpwall() end break end - table.insert(pws, getpw(pw.pw_uid)) + table.insert(pws, getpw(pw)) end ffi.C.endpwent() return pws @@ -188,7 +188,7 @@ local function getgrall() end break end - table.insert(grs, getpw(gr.gr_gid)) + table.insert(grs, getgr(gr)) end ffi.C.endgrent() return grs @@ -200,12 +200,7 @@ end -- password database is traversed first time. -- -- [1]: https://github.com/systemd/systemd/issues/9585 --- --- It is disabled on FreeBSD due to gh-4428: getpwall() hangs on --- FreeBSD 12. -if jit.os ~= 'BSD' then - pcall(getpwall) -end +pcall(getpwall) return { getpw = getpw, diff --git a/test/app-tap/pwd.skipcond b/test/app-tap/pwd.skipcond deleted file mode 100644 index 7950a5d93..000000000 --- a/test/app-tap/pwd.skipcond +++ /dev/null @@ -1,8 +0,0 @@ -import platform - -# Disabled on FreeBSD due to fail #4271: -# Data segment size exceeds process limit -if platform.system() == 'FreeBSD': - self.skip = 1 - -# vim: set ft=python: -- 2.22.0