From 1d358ebb1c66bf9ef24f5f2acf3b442472154e05 Mon Sep 17 00:00:00 2001 From: Samuli Thomasson Date: Thu, 5 Jun 2025 21:29:12 +0200 Subject: [PATCH] handle buffer too small for getgrnam_r Signed-off-by: Samuli Thomasson --- .../unix/build/linux-derivation-builder.cc | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/libstore/unix/build/linux-derivation-builder.cc b/src/libstore/unix/build/linux-derivation-builder.cc index ad477f7fb..4318485ec 100644 --- a/src/libstore/unix/build/linux-derivation-builder.cc +++ b/src/libstore/unix/build/linux-derivation-builder.cc @@ -252,7 +252,7 @@ struct ChrootLinuxDerivationBuilder : LinuxDerivationBuilder struct group * gr = nullptr; long bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); if (bufsize == -1) bufsize = 16384; - std::vector buffer(bufsize); + std::vector buffer; for (const auto & group_entry : settings.supplementaryGroups.get()) { std::string group_name = group_entry; @@ -270,9 +270,17 @@ struct ChrootLinuxDerivationBuilder : LinuxDerivationBuilder } } - int ret = getgrnam_r(group_name.c_str(), &grp, buffer.data(), buffer.size(), &gr); - if (ret != 0) - throw Error("getgrnam_r failed for group '%s': %s", group_name, strerror(ret)); + while (true) { + buffer.resize(bufsize); + int ret = getgrnam_r(group_name.c_str(), &grp, buffer.data(), buffer.size(), &gr); + if (ret == 0) { + break; + } else if (ret == ERANGE) { // buffer too small + bufsize *= 2; + } else if (ret != 0) + throw Error("getgrnam_r failed for group '%s': %s", group_name, strerror(ret)); + } + if (!gr) { debug("Supplementary group '%s' not found", group_name); continue;