[tarantool-patches] [PATCH] lua: pwd: fix passwd and group traversal

Alexander Turenko alexander.turenko at tarantool.org
Fri Aug 23 04:57:34 MSK 2019


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<struct passwd> to
pwd.getgr() and to pass cdata<struct group> 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<struct passwd>
/ cdata<struct group> 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





More information about the Tarantool-patches mailing list