From: Roy Marples Date: Tue, 15 Oct 2019 12:40:32 +0000 (+0100) Subject: Revert "compat: Use more portable setproctitle from nginx" X-Git-Tag: v8.1.1~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c054a360e97e1c4e50c56e38aec730767fadd11e;p=thirdparty%2Fdhcpcd.git Revert "compat: Use more portable setproctitle from nginx" This reverts commit cbcb352f10de5ba5185860f20e148509081f9d2f. --- diff --git a/compat/setproctitle.c b/compat/setproctitle.c index 9350e5ee..f5ff0ac0 100644 --- a/compat/setproctitle.c +++ b/compat/setproctitle.c @@ -1,136 +1,156 @@ /* - * 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 + * + * 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 +#include + +#include #include #include +#include #include +#include #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; } diff --git a/compat/setproctitle.h b/compat/setproctitle.h index 18249947..2fe685f1 100644 --- a/compat/setproctitle.h +++ b/compat/setproctitle.h @@ -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 + * + * 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 diff --git a/src/dhcpcd.c b/src/dhcpcd.c index 85d9081f..193414ed 100644 --- a/src/dhcpcd.c +++ b/src/dhcpcd.c @@ -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 */