]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Revert "compat: Use more portable setproctitle from nginx"
authorRoy Marples <roy@marples.name>
Tue, 15 Oct 2019 12:40:32 +0000 (13:40 +0100)
committerRoy Marples <roy@marples.name>
Tue, 15 Oct 2019 12:40:32 +0000 (13:40 +0100)
This reverts commit cbcb352f10de5ba5185860f20e148509081f9d2f.

compat/setproctitle.c
compat/setproctitle.h
src/dhcpcd.c

index 9350e5eedb9ce7e2017ba87ef7df3084d6990179..f5ff0ac0a46f3b24096bcce0556fa91d0db58a76 100644 (file)
 /*
- * Copyright (C) 2002-2019 Igor Sysoev
- * Copyright (C) 2011-2019 Nginx, Inc.
- * All rights reserved.
+ * lxc: linux Container library
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
+ * (C) Copyright IBM Corp. 2007, 2008
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * Authors:
+ * Daniel Lezcano <daniel.lezcano at free.fr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+#include <sys/prctl.h>
+#include <sys/syscall.h>
+
+#include <fcntl.h>
 #include <stdarg.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "config.h"
 
-#ifdef __sun
-#define SETPROCTITLE_PAD       ' '
+#define prctl_arg(x) ((unsigned long)x)
+
+/*
+ * Sets the process title to the specified title. Note that this may fail if
+ * the kernel doesn't support PR_SET_MM_MAP (kernels <3.18).
+ */
+int setproctitle(const char *fmt, ...)
+{
+       char title[1024], *tp, *progname;
+       va_list args;
+       int fd, i;
+       char *buf_ptr, *tmp_proctitle;
+       char buf[BUFSIZ];
+       int ret = 0;
+       ssize_t bytes_read = 0;
+       size_t len;
+       static char *proctitle = NULL;
+
+#if 0
+       progname = getprogname();
 #else
-#define        SETPROCTITLE_PAD        '\0'
+       progname = "dhcpcd";
 #endif
+       tp = title;
+       tp += snprintf(title, sizeof(title), "%s: ", progname);
 
-static int setproctitle_argc;
-static char *setproctitle_argv_last;
-static char **setproctitle_argv;
-static char *setproctitle_buf;
-
-int
-setproctitle_init(int argc, char **argv)
-{
-       size_t i, len;
-       char *p;
+       va_start(args, fmt);
+       vsnprintf(tp, sizeof(title) - strlen(progname), fmt, args);
+       va_end(args);
 
-       len = 0;
-       for (i = 0; environ[i] != NULL; i++)
-                len += strlen(environ[i]) + 1;
-       if ((setproctitle_buf = malloc(len)) == NULL)
+       /*
+        * We don't really need to know all of this stuff, but unfortunately
+        * PR_SET_MM_MAP requires us to set it all at once, so we have to
+        * figure it out anyway.
+        */
+       unsigned long start_data, end_data, start_brk, start_code, end_code,
+           start_stack, arg_start, arg_end, env_start, env_end;
+       long brk_val;
+       struct prctl_mm_map prctl_map;
+
+       fd = open("/proc/self/stat", O_RDONLY);
+       if (fd == -1)
+               return -1;
+       bytes_read = read(fd, buf, sizeof(buf) - 1);
+       close(fd);
+       if (bytes_read == -1)
                return -1;
 
-       setproctitle_argc = argc;
-       setproctitle_argv = argv;
-       setproctitle_argv_last = setproctitle_argv[0];
-       for (i = 0; setproctitle_argv[i] != NULL; i++) {
-               if (setproctitle_argv_last == setproctitle_argv[i])
-                       setproctitle_argv_last = setproctitle_argv[i] +
-                           strlen(setproctitle_argv[i]) + 1;
-       }
+       buf[bytes_read] = '\0';
 
-       p = setproctitle_buf;
-       for (i = 0; environ[i] != NULL; i++) {
-               if (setproctitle_argv_last != environ[i])
-                       continue;
-               len = strlen(environ[i]) + 1;
-               setproctitle_argv_last = environ[i] + len;
-               strlcpy(p, environ[i], len);
-               environ[i] = p;
-               p += len;
+       /* Skip the first 25 fields, column 26-28 are start_code, end_code,
+        * and start_stack */
+       buf_ptr = strchr(buf, ' ');
+       for (i = 0; i < 24; i++) {
+               if (!buf_ptr)
+                       return -1;
+               buf_ptr = strchr(buf_ptr + 1, ' ');
        }
+       if (!buf_ptr)
+               return -1;
 
-       setproctitle_argv_last--;
-       return 0;
-}
-
-void
-setproctitle_free(void)
-{
-
-       free(setproctitle_buf);
-}
+       i = sscanf(buf_ptr, "%lu %lu %lu", &start_code, &end_code, &start_stack);
+       if (i != 3)
+               return -1;
 
-void
-setproctitle(const char *fmt, ...)
-{
-       const char *progname;
-       char *p;
-       int n;
-       va_list args;
-#if 0
-       progname = getprogname();
-#else
-       progname = "dhcpcd";
-#endif
+       /* Skip the next 19 fields, column 45-51 are start_data to arg_end */
+       for (i = 0; i < 19; i++) {
+               if (!buf_ptr)
+                       return -1;
+               buf_ptr = strchr(buf_ptr + 1, ' ');
+       }
 
-       setproctitle_argv[1] = NULL;
-#define        LAST_SIZE       (size_t)(setproctitle_argv_last - p)
+       if (!buf_ptr)
+               return -1;
 
-       p = setproctitle_argv[0];
-       n = snprintf(p, LAST_SIZE, "%s: ", progname);
-       if (n == -1)
-               return;
-       p += n;
+       i = sscanf(buf_ptr, "%lu %lu %lu %*u %*u %lu %lu", &start_data,
+                  &end_data, &start_brk, &env_start, &env_end);
+       if (i != 5)
+               return -1;
 
-       va_start(args, fmt);
-       n = vsnprintf(p, LAST_SIZE, fmt, args);
-       va_end(args);
-       if (n == -1)
-               return;
-       p += n;
+       /* Include the null byte here, because in the calculations below we
+        * want to have room for it. */
+       len = strlen(title) + 1;
 
-#ifdef __sun
-       size_t len;
-       int i;
-
-       len = 0;
-       for (i = 0; i < setproctitle_argc; i++)
-               len += strlen(setproctitle_argv[i]) + 1;
-
-       if (len > (size_t)(p - setproctitle_argv[0])) {
-               p += strlcpy(p, " (", LAST_SIZE);
-               for (i = 0; i < setproctitle_argc; i++) {
-                       p += strlcpy(p, setproctitle_argv[i], LAST_SIZE);
-                       p += strlcpy(p, " ", LAST_SIZE);
-               }
-       }
-#endif
+       tmp_proctitle = realloc(proctitle, len);
+       if (!tmp_proctitle)
+               return -1;
 
-       if (setproctitle_argv_last - p > 0)
-               memset(p, SETPROCTITLE_PAD, LAST_SIZE);
+       proctitle = tmp_proctitle;
+
+       arg_start = (unsigned long)proctitle;
+       arg_end = arg_start + len;
+
+       brk_val = syscall(__NR_brk, 0);
+
+       prctl_map = (struct prctl_mm_map){
+           .start_code = start_code,
+           .end_code = end_code,
+           .start_stack = start_stack,
+           .start_data = start_data,
+           .end_data = end_data,
+           .start_brk = start_brk,
+           .brk = (unsigned long long)brk_val,
+           .arg_start = arg_start,
+           .arg_end = arg_end,
+           .env_start = env_start,
+           .env_end = env_end,
+           .auxv = NULL,
+           .auxv_size = 0,
+           .exe_fd = (unsigned int)-1,
+       };
+
+       ret = prctl(PR_SET_MM, prctl_arg(PR_SET_MM_MAP), prctl_arg(&prctl_map),
+                   prctl_arg(sizeof(prctl_map)), prctl_arg(0));
+       if (ret == 0)
+               (void)strlcpy((char *)arg_start, title, len);
+       return ret;
 }
index 1824994780d7ae7f27238b3453698258a50f3ee2..2fe685f144bf35f658aafddb0ec68bd993ba9fc7 100644 (file)
@@ -1,28 +1,24 @@
 /*
- * Copyright (C) 2002-2019 Igor Sysoev
- * Copyright (C) 2011-2019 Nginx, Inc.
- * All rights reserved.
+ * lxc: linux Container library
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
+ * (C) Copyright IBM Corp. 2007, 2008
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * Authors:
+ * Daniel Lezcano <daniel.lezcano at free.fr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #ifndef SETPROCTITLE_H
@@ -36,7 +32,5 @@
 #endif
 #endif /* !__printflike */
 
-int setproctitle_init(int, char **);
-void setproctitle_free(void);
-__printflike(1, 2) void setproctitle(const char *, ...);
+__printflike(1, 2) int setproctitle(const char *, ...);
 #endif
index 85d9081f56298460e64e4b58dcdb68f9f32d5e24..193414ed67bbd6fb867bf14e3abd61c18b0633a9 100644 (file)
@@ -1549,47 +1549,6 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx, struct fd_list *fd,
        return 0;
 }
 
-static int
-dhcpcd_saveargv(struct dhcpcd_ctx *ctx, int argc, char **argv)
-{
-#ifdef SETPROCTITLE_H
-       int i;
-
-       ctx->argv = reallocarray(ctx->argv, (size_t)argc + 1, sizeof(char *));
-       if (ctx->argv == NULL) {
-               logerr(__func__);
-               return -1;
-       }
-
-       ctx->argc = argc;
-       for (i = 0; i < argc; i++) {
-               if ((ctx->argv[i] = strdup(argv[i])) == NULL) {
-                       logerr(__func__);
-                       return -1;
-               }
-       }
-
-       ctx->argv[i] = NULL;
-#else
-       ctx->argv = argv;
-       ctx->argc = argc;
-#endif
-       return 0;
-
-}
-
-static void
-dhcpcd_freeargv(struct dhcpcd_ctx *ctx)
-{
-#ifdef SETPROCTITLE_H
-       int i;
-
-       for (i = 0; i < ctx->argc; i++)
-               free(ctx->argv[i]);
-       free(ctx->argv);
-#endif
-}
-
 int
 main(int argc, char **argv)
 {
@@ -1732,8 +1691,8 @@ main(int argc, char **argv)
        logsetopts(logopts);
        logopen(ctx.logfile);
 
-       if (dhcpcd_saveargv(&ctx, argc, argv) == -1)
-               goto exit_failure;
+       ctx.argv = argv;
+       ctx.argc = argc;
        ctx.ifc = argc - optind;
        ctx.ifv = argv + optind;
 
@@ -1743,7 +1702,7 @@ main(int argc, char **argv)
                        goto printpidfile;
                goto exit_failure;
        }
-       opt = add_options(&ctx, NULL, ifo, ctx.argc, ctx.argv);
+       opt = add_options(&ctx, NULL, ifo, argc, argv);
        if (opt != 1) {
                if (ctx.options & DHCPCD_PRINT_PIDFILE)
                        goto printpidfile;
@@ -1758,7 +1717,7 @@ main(int argc, char **argv)
                        ifo = read_config(&ctx, argv[optind], NULL, NULL);
                        if (ifo == NULL)
                                goto exit_failure;
-                       add_options(&ctx, NULL, ifo, ctx.argc, ctx.argv);
+                       add_options(&ctx, NULL, ifo, argc, argv);
                }
                if_printoptions();
 #ifdef INET
@@ -1881,7 +1840,7 @@ printpidfile:
                        logerr("%s: if_discover", __func__);
                        goto exit_failure;
                }
-               ifp = if_find(ctx.ifaces, ctx.argv[optind]);
+               ifp = if_find(ctx.ifaces, argv[optind]);
                if (ifp == NULL) {
                        ifp = calloc(1, sizeof(*ifp));
                        if (ifp == NULL) {
@@ -1889,7 +1848,7 @@ printpidfile:
                                goto exit_failure;
                        }
                        if (optind != argc)
-                               strlcpy(ctx.pidfile, ctx.argv[optind],
+                               strlcpy(ctx.pidfile, argv[optind],
                                    sizeof(ctx.pidfile));
                        ifp->ctx = &ctx;
                        TAILQ_INSERT_HEAD(ctx.ifaces, ifp, next);
@@ -2025,9 +1984,6 @@ printpidfile:
        logdebugx(PACKAGE "-" VERSION " starting");
        ctx.options |= DHCPCD_STARTED;
 
-#ifdef SETPROCTITLE_H
-       setproctitle_init(argc, argv);
-#endif
        setproctitle("%s%s%s",
            ctx.options & DHCPCD_MASTER ? "[master]" : argv[optind],
            ctx.options & DHCPCD_IPV4 ? " [ip4]" : "",
@@ -2088,7 +2044,7 @@ printpidfile:
 
        TAILQ_FOREACH(ifp, ctx.ifaces, next) {
                if (ifp->active)
-                       dhcpcd_initstate1(ifp, ctx.argc, ctx.argv, 0);
+                       dhcpcd_initstate1(ifp, argc, argv, 0);
        }
        if_learnaddrs(&ctx, ctx.ifaces, &ifaddrs);
 
@@ -2197,10 +2153,6 @@ exit1:
                loginfox(PACKAGE " exited");
        logclose();
        free(ctx.logfile);
-       dhcpcd_freeargv(&ctx);
-#ifdef SETPROCTITLE_H
-       setproctitle_free();
-#endif
 #ifdef USE_SIGNALS
        if (ctx.options & DHCPCD_FORKED)
                _exit(i); /* so atexit won't remove our pidfile */