From b9f80409d70ea0ff6d8dcf028aa701bee5bd48d7 Mon Sep 17 00:00:00 2001 From: Alexander Kriventsov Date: Mon, 3 Jun 2019 18:11:56 +0300 Subject: [PATCH] getgrgid_r fails with ERANGE if buffer is too small. Retry with a larger buffer. Signed-off-by: Alexander Kriventsov --- src/lxc/cmd/lxc_user_nic.c | 23 ++++++++++++++++++++++- src/lxc/utils.h | 4 ++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/lxc/cmd/lxc_user_nic.c b/src/lxc/cmd/lxc_user_nic.c index 84823bd5d..40c9aa9d7 100644 --- a/src/lxc/cmd/lxc_user_nic.c +++ b/src/lxc/cmd/lxc_user_nic.c @@ -206,7 +206,28 @@ static char **get_groupnames(void) } for (i = 0; i < ngroups; i++) { - ret = getgrgid_r(group_ids[i], &grent, buf, bufsize, &grentp); + while ((ret = getgrgid_r(group_ids[i], &grent, buf, bufsize, &grentp)) == ERANGE) { + bufsize <<= 1; + if (bufsize > MAX_GRBUF_SIZE) { + usernic_error("Failed to get group members: %u\n", + group_ids[i]); + free(buf); + free(group_ids); + free_groupnames(groupnames); + return NULL; + } + char *new_buf = realloc(buf, bufsize); + if (!new_buf) { + usernic_error("Failed to allocate memory while getting group " + "names: %s\n", + strerror(errno)); + free(buf); + free(group_ids); + free_groupnames(groupnames); + return NULL; + } + buf = new_buf; + } if (!grentp) { if (ret == 0) usernic_error("%s", "Could not find matched group record\n"); diff --git a/src/lxc/utils.h b/src/lxc/utils.h index 747e14b6e..9f1c21ddd 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -26,6 +26,10 @@ /* Properly support loop devices on 32bit systems. */ #define _FILE_OFFSET_BITS 64 +#ifndef MAX_GRBUF_SIZE +#define MAX_GRBUF_SIZE 65536 +#endif + #include #include #include -- 2.47.2