From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 107375 invoked by alias); 25 Jun 2018 14:25:10 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Received: (qmail 107139 invoked by uid 89); 25 Jun 2018 14:24:46 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_HELO_PASS,TIME_LIMIT_EXCEEDED autolearn=unavailable version=3.3.2 spammy=Hx-languages-length:3935 X-HELO: mx1.redhat.com Date: Mon, 25 Jun 2018 14:25:00 -0000 To: libc-alpha@sourceware.org Subject: [PATCH] nscd restart: Use malloc instead of extend_alloca [BZ #18023] User-Agent: Heirloom mailx 12.5 7/5/10 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-Id: <20180625142403.CCE1943994575@oldenburg.str.redhat.com> From: fweimer@redhat.com (Florian Weimer) X-SW-Source: 2018-06/txt/msg00730.txt.bz2 This introduces a separate function, read_cmdline, which reads the contents of /proc/self/cmdline into a heap-allocated buffer. 2018-06-25 Florian Weimer [BZ #18023] * nscd/connections.c (read_cmdline): New function. (restart): Use it. Update comment. diff --git a/nscd/connections.c b/nscd/connections.c index 1b3bae4eeb..cdb0c86bb5 100644 --- a/nscd/connections.c +++ b/nscd/connections.c @@ -1281,64 +1281,83 @@ request from '%s' [%ld] not handled due to missing permission"), } } - -/* Restart the process. */ -static void -restart (void) +static char * +read_cmdline (size_t *size) { - /* First determine the parameters. We do not use the parameters - passed to main() since in case nscd is started by running the - dynamic linker this will not work. Yes, this is not the usual - case but nscd is part of glibc and we occasionally do this. */ - size_t buflen = 1024; - char *buf = alloca (buflen); - size_t readlen = 0; int fd = open ("/proc/self/cmdline", O_RDONLY); - if (fd == -1) + if (fd < 0) + return NULL; + size_t current = 0; + size_t limit = 1024; + char *buffer = malloc (limit); + if (buffer == NULL) { - dbg_log (_("\ -cannot open /proc/self/cmdline: %s; disabling paranoia mode"), - strerror (errno)); - - paranoia = 0; - return; + close (fd); + errno = ENOMEM; + return NULL; } - while (1) { - ssize_t n = TEMP_FAILURE_RETRY (read (fd, buf + readlen, - buflen - readlen)); + if (current == limit) + { + char *newptr; + if (2 * limit < limit + || (newptr = realloc (buffer, 2 * limit)) == NULL) + { + free (buffer); + close (fd); + errno = ENOMEM; + return NULL; + } + buffer = newptr; + limit *= 2; + } + + ssize_t n = TEMP_FAILURE_RETRY (read (fd, buffer + current, + limit - current)); if (n == -1) { - dbg_log (_("\ -cannot read /proc/self/cmdline: %s; disabling paranoia mode"), - strerror (errno)); - + int e = errno; + free (buffer); close (fd); - paranoia = 0; - return; + errno = e; + return NULL; } - - readlen += n; - - if (readlen < buflen) + if (n == 0) break; - - /* We might have to extend the buffer. */ - size_t old_buflen = buflen; - char *newp = extend_alloca (buf, buflen, 2 * buflen); - buf = memmove (newp, buf, old_buflen); + current += n; } close (fd); + *size = current; + return buffer; +} + + +/* Restart the process. */ +static void +restart (void) +{ + /* First determine the parameters. We do not use the parameters + passed to main() because then nscd would would use the system + libc after restarting even if it was started by a non-system + dynamic linker during glibc testing. */ + size_t readlen; + char *cmdline = read_cmdline (&readlen); + if (cmdline == NULL) + { + dbg_log (_("\ +cannot open /proc/self/cmdline: %m; disabling paranoia mode")); + paranoia = 0; + return; + } /* Parse the command line. Worst case scenario: every two characters form one parameter (one character plus NUL). */ char **argv = alloca ((readlen / 2 + 1) * sizeof (argv[0])); int argc = 0; - char *cp = buf; - while (cp < buf + readlen) + for (char *cp = cmdline; cp < cmdline + readlen;) { argv[argc++] = cp; cp = (char *) rawmemchr (cp, '\0') + 1; @@ -1355,6 +1374,7 @@ cannot change to old UID: %s; disabling paranoia mode"), strerror (errno)); paranoia = 0; + free (cmdline); return; } @@ -1366,6 +1386,7 @@ cannot change to old GID: %s; disabling paranoia mode"), ignore_value (setuid (server_uid)); paranoia = 0; + free (cmdline); return; } } @@ -1383,6 +1404,7 @@ cannot change to old working directory: %s; disabling paranoia mode"), ignore_value (setgid (server_gid)); } paranoia = 0; + free (cmdline); return; } @@ -1431,6 +1453,7 @@ cannot change to old working directory: %s; disabling paranoia mode"), dbg_log (_("cannot change current working directory to \"/\": %s"), strerror (errno)); paranoia = 0; + free (cmdline); /* Reenable the databases. */ time_t now = time (NULL);