From: fweimer@redhat.com (Florian Weimer)
To: libc-alpha@sourceware.org
Subject: [PATCH] nscd restart: Use malloc instead of extend_alloca [BZ #18023]
Date: Mon, 25 Jun 2018 14:25:00 -0000 [thread overview]
Message-ID: <20180625142403.CCE1943994575@oldenburg.str.redhat.com> (raw)
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 <fweimer@redhat.com>
[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);
next reply other threads:[~2018-06-25 14:25 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-25 14:25 Florian Weimer [this message]
2018-06-25 15:04 ` Andreas Schwab
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=20180625142403.CCE1943994575@oldenburg.str.redhat.com \
--to=fweimer@redhat.com \
--cc=libc-alpha@sourceware.org \
/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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).