diff options
author | 2016-01-17 12:21:45 -0800 | |
---|---|---|
committer | 2016-01-21 13:09:11 -0800 | |
commit | 6cc7eb47142dcad1cf277ccf31c38fc53746e45e (patch) | |
tree | 6c029356fe6b2a580de4875c1e4201e4881deea9 /paludis/util/process.cc | |
parent | 1e359553c2e5da698318714bd77884da0288f4d8 (diff) | |
download | paludis-6cc7eb47142dcad1cf277ccf31c38fc53746e45e.tar.gz paludis-6cc7eb47142dcad1cf277ccf31c38fc53746e45e.tar.xz |
paludis: POSIX_ME_HARDER accounts repository
POSIX permits an indefinite required buffer size for querying GECOS fields.
This is currently used in three locations. Previously, paludis would assume
that it could perform a sysconf call to retrieve the requisite buffer size for
ensuring that the subsequent GECOS field query would not receive a -ERANGE
error. However, as it turns out, this is actually a problem even with GLIBC
where the NSS may end up querying a service which has a larger field value
for the `struct pwd` (glibc sets the return value to the NSS buffer length, aka
1k, but may end up querying a service which provides a larger response).
Use local wrappers which perform the size adjustment to avoid an undersized
buffer. Localise the functions which query the various GECOS fields which
comprise the persona into util.
Diffstat (limited to 'paludis/util/process.cc')
-rw-r--r-- | paludis/util/process.cc | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/paludis/util/process.cc b/paludis/util/process.cc index b4b553db1..380d671d6 100644 --- a/paludis/util/process.cc +++ b/paludis/util/process.cc @@ -17,6 +17,7 @@ * Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <paludis/util/persona.hh> #include <paludis/util/process.hh> #include <paludis/util/pimp-impl.hh> #include <paludis/util/pipe.hh> @@ -806,17 +807,14 @@ Process::run() if (0 != ::setgid(_imp->setgid)) throw ProcessError("setgid() failed"); - int buflen(::sysconf(_SC_GETPW_R_SIZE_MAX)); - if (-1 == buflen) - buflen = 1 << 16; + struct passwd pwd; + struct passwd *result; + std::vector<char> buffer; - std::unique_ptr<char []> buf(new char[buflen]); - struct passwd pw; - struct passwd * pw_result(nullptr); - if (0 != getpwuid_r(_imp->setuid, &pw, buf.get(), buflen, &pw_result) || nullptr == pw_result) + if (0 != getpwuid_r_s(_imp->setuid, buffer, pwd, result) || result == nullptr) throw ProcessError("getpwuid_r() failed"); - if (0 != ::initgroups(pw_result->pw_name, getgid())) + if (0 != ::initgroups(pwd.pw_name, getgid())) throw ProcessError("initgroups() failed"); if (0 != ::setuid(_imp->setuid)) |