Tarantool development patches archive
 help / color / mirror / Atom feed
From: Alexander Turenko <alexander.turenko@tarantool.org>
To: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
Cc: Alexander Turenko <alexander.turenko@tarantool.org>,
	tarantool-patches@freelists.org
Subject: [tarantool-patches] [PATCH] lua: pwd: fix passwd and group traversal
Date: Fri, 23 Aug 2019 04:57:34 +0300	[thread overview]
Message-ID: <5545c38a61fe1867743a75b6bb4767b8e87c629e.1566524401.git.alexander.turenko@tarantool.org> (raw)

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

             reply	other threads:[~2019-08-23  1:58 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-23  1:57 Alexander Turenko [this message]
2019-08-23 20:26 ` [tarantool-patches] " Vladislav Shpilevoy
2019-08-25 11:07   ` Alexander Turenko
2019-08-25 18:03     ` Vladislav Shpilevoy
2019-08-26  9:43       ` Alexander Turenko
2019-08-26 15:08 ` Kirill Yukhin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5545c38a61fe1867743a75b6bb4767b8e87c629e.1566524401.git.alexander.turenko@tarantool.org \
    --to=alexander.turenko@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --cc=v.shpilevoy@tarantool.org \
    --subject='Re: [tarantool-patches] [PATCH] lua: pwd: fix passwd and group traversal' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox