From 1eec7348a5e7f9d38f34d25bf7fba9f92ed02886 Mon Sep 17 00:00:00 2001 From: Brad Davidson Date: Mon, 27 Jul 2020 12:09:21 -0700 Subject: [PATCH] Call setproctitle to conceal node args in ps output This is related to #2014. Signed-off-by: Brad Davidson --- go.mod | 1 + go.sum | 2 + pkg/cli/agent/agent.go | 5 + pkg/cli/server/server.go | 5 + pkg/nodeconfig/nodeconfig.go | 3 +- .../erikdubbelboer/gspt/.travis.yml | 4 + vendor/github.com/erikdubbelboer/gspt/LICENSE | 20 ++ .../github.com/erikdubbelboer/gspt/README.md | 28 ++ vendor/github.com/erikdubbelboer/gspt/gspt.go | 71 ++++ .../erikdubbelboer/gspt/setproctitle.h | 307 ++++++++++++++++++ vendor/modules.txt | 2 + 11 files changed, 447 insertions(+), 1 deletion(-) create mode 100644 vendor/github.com/erikdubbelboer/gspt/.travis.yml create mode 100644 vendor/github.com/erikdubbelboer/gspt/LICENSE create mode 100644 vendor/github.com/erikdubbelboer/gspt/README.md create mode 100644 vendor/github.com/erikdubbelboer/gspt/gspt.go create mode 100644 vendor/github.com/erikdubbelboer/gspt/setproctitle.h diff --git a/go.mod b/go.mod index 57a656ef9c..8cd9cdd99a 100644 --- a/go.mod +++ b/go.mod @@ -80,6 +80,7 @@ require ( github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f github.com/docker/docker v1.4.2-0.20191205034852-d163fbba3c82 github.com/docker/go-metrics v0.0.1 // indirect + github.com/erikdubbelboer/gspt v0.0.0-20190125194910-e68493906b83 github.com/go-bindata/go-bindata v3.1.2+incompatible github.com/go-sql-driver/mysql v1.4.1 github.com/gogo/googleapis v1.3.0 // indirect diff --git a/go.sum b/go.sum index 7646d3fb14..6d1f9afe02 100644 --- a/go.sum +++ b/go.sum @@ -198,6 +198,8 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/erikdubbelboer/gspt v0.0.0-20190125194910-e68493906b83 h1:ngHdSomn2MyugZYKHiycad2xERwIrmMlET7A0lC0UU4= +github.com/erikdubbelboer/gspt v0.0.0-20190125194910-e68493906b83/go.mod h1:v6o7m/E9bfvm79dE1iFiF+3T7zLBnrjYjkWMa1J+Hv0= github.com/euank/go-kmsg-parser v2.0.0+incompatible h1:cHD53+PLQuuQyLZeriD1V/esuG4MuU0Pjs5y6iknohY= github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= diff --git a/pkg/cli/agent/agent.go b/pkg/cli/agent/agent.go index a4520ac5dd..2630cfcacf 100644 --- a/pkg/cli/agent/agent.go +++ b/pkg/cli/agent/agent.go @@ -6,6 +6,7 @@ import ( "os" "runtime" + "github.com/erikdubbelboer/gspt" "github.com/rancher/k3s/pkg/agent" "github.com/rancher/k3s/pkg/cli/cmds" "github.com/rancher/k3s/pkg/datadir" @@ -18,6 +19,10 @@ import ( ) func Run(ctx *cli.Context) error { + // hide process arguments from ps output, since they may contain + // database credentials or other secrets. + gspt.SetProcTitle(os.Args[0] + " agent") + if os.Getuid() != 0 && runtime.GOOS != "windows" { return fmt.Errorf("agent must be ran as root") } diff --git a/pkg/cli/server/server.go b/pkg/cli/server/server.go index 2fa536fd1f..9a2439b89f 100644 --- a/pkg/cli/server/server.go +++ b/pkg/cli/server/server.go @@ -9,6 +9,7 @@ import ( "strings" systemd "github.com/coreos/go-systemd/daemon" + "github.com/erikdubbelboer/gspt" "github.com/pkg/errors" "github.com/rancher/k3s/pkg/agent" "github.com/rancher/k3s/pkg/cli/cmds" @@ -39,6 +40,10 @@ func run(app *cli.Context, cfg *cmds.Server) error { err error ) + // hide process arguments from ps output, since they may contain + // database credentials or other secrets. + gspt.SetProcTitle(os.Args[0] + " server") + if !cfg.DisableAgent && os.Getuid() != 0 && !cfg.Rootless { return fmt.Errorf("must run as root unless --disable-agent is specified") } diff --git a/pkg/nodeconfig/nodeconfig.go b/pkg/nodeconfig/nodeconfig.go index 10fe16b1f6..09c97ae019 100644 --- a/pkg/nodeconfig/nodeconfig.go +++ b/pkg/nodeconfig/nodeconfig.go @@ -26,7 +26,7 @@ const ( func getNodeArgs() (string, error) { nodeArgsList := []string{} for _, arg := range os.Args[1:] { - if strings.Contains(arg, "=") { + if strings.HasPrefix(arg, "--") && strings.Contains(arg, "=") { parsedArg := strings.SplitN(arg, "=", 2) nodeArgsList = append(nodeArgsList, parsedArg...) continue @@ -89,6 +89,7 @@ func SetNodeConfigAnnotations(node *corev1.Node) (bool, error) { if node.Annotations[NodeConfigHashAnnotation] == encoded { return false, nil } + node.Annotations[NodeEnvAnnotation] = nodeEnv node.Annotations[NodeArgsAnnotation] = nodeArgs node.Annotations[NodeConfigHashAnnotation] = encoded diff --git a/vendor/github.com/erikdubbelboer/gspt/.travis.yml b/vendor/github.com/erikdubbelboer/gspt/.travis.yml new file mode 100644 index 0000000000..8d61700ec2 --- /dev/null +++ b/vendor/github.com/erikdubbelboer/gspt/.travis.yml @@ -0,0 +1,4 @@ +language: go +go: + - 1.1 + - tip diff --git a/vendor/github.com/erikdubbelboer/gspt/LICENSE b/vendor/github.com/erikdubbelboer/gspt/LICENSE new file mode 100644 index 0000000000..c718359d32 --- /dev/null +++ b/vendor/github.com/erikdubbelboer/gspt/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Erik Dubbelboer + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/erikdubbelboer/gspt/README.md b/vendor/github.com/erikdubbelboer/gspt/README.md new file mode 100644 index 0000000000..6e3c6fefe9 --- /dev/null +++ b/vendor/github.com/erikdubbelboer/gspt/README.md @@ -0,0 +1,28 @@ +gspt +==== + +`setproctitle()` package for Go. + +[![Build Status](https://travis-ci.org/erikdubbelboer/gspt.png?branch=master)](https://travis-ci.org/erikdubbelboer/gspt) + +-------------------------------- + +Installation +------------ + +Simple install the package to your [$GOPATH](https://github.com/golang/go/wiki/GOPATH) with the [go tool](http://golang.org/cmd/go/): +```bash +go get github.com/erikdubbelboer/gspt +``` +Make sure [Git is installed](http://git-scm.com/downloads) on your machine and in your system's `PATH`. + +Usage +----- + +```go +import "github.com/erikdubbelboer/gspt" + +gspt.SetProcTitle("some title") +``` + +Please check the [documentation](http://godoc.org/github.com/erikdubbelboer/gspt) for more details. diff --git a/vendor/github.com/erikdubbelboer/gspt/gspt.go b/vendor/github.com/erikdubbelboer/gspt/gspt.go new file mode 100644 index 0000000000..5cfdeeb6b3 --- /dev/null +++ b/vendor/github.com/erikdubbelboer/gspt/gspt.go @@ -0,0 +1,71 @@ +package gspt + +/* + +#include "setproctitle.h" + +*/ +import "C" + +import ( + "os" + "strings" + "unsafe" +) + +const ( + // These values must match the return values for spt_init1() used in C. + HaveNone = 0 + HaveNative = 1 + HaveReplacement = 2 +) + +var ( + HaveSetProcTitle int + HaveSetProcTitleFast int +) + +func init() { + HaveSetProcTitle = int(C.spt_init1()) + HaveSetProcTitleFast = int(C.spt_fast_init1()) + + if HaveSetProcTitle == HaveReplacement { + newArgs := make([]string, len(os.Args)) + for i, s := range os.Args { + // Use cgo to force go to make copies of the strings. + cs := C.CString(s) + newArgs[i] = C.GoString(cs) + C.free(unsafe.Pointer(cs)) + } + os.Args = newArgs + + env := os.Environ() + for _, kv := range env { + skv := strings.SplitN(kv, "=", 2) + os.Setenv(skv[0], skv[1]) + } + + argc := C.int(len(os.Args)) + arg0 := C.CString(os.Args[0]) + defer C.free(unsafe.Pointer(arg0)) + + C.spt_init2(argc, arg0) + + // Restore the original title. + SetProcTitle(os.Args[0]) + } +} + +func SetProcTitle(title string) { + cs := C.CString(title) + defer C.free(unsafe.Pointer(cs)) + + C.spt_setproctitle(cs) +} + +func SetProcTitleFast(title string) { + cs := C.CString(title) + defer C.free(unsafe.Pointer(cs)) + + C.spt_setproctitle_fast(cs) +} diff --git a/vendor/github.com/erikdubbelboer/gspt/setproctitle.h b/vendor/github.com/erikdubbelboer/gspt/setproctitle.h new file mode 100644 index 0000000000..ea92890d6d --- /dev/null +++ b/vendor/github.com/erikdubbelboer/gspt/setproctitle.h @@ -0,0 +1,307 @@ +/* ========================================================================== + * setproctitle.h - Linux/Darwin setproctitle. + * -------------------------------------------------------------------------- + * Copyright (C) 2010 William Ahern + * Copyright (C) 2013 Salvatore Sanfilippo + * Copyright (C) 2013 Stam He + * Copyright (C) 2013 Erik Dubbelboer + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * ========================================================================== + */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include // NULL size_t +#include // va_list va_start va_end +#include // malloc(3) setenv(3) clearenv(3) setproctitle(3) getprogname(3) +#include // vsnprintf(3) snprintf(3) +#include // strlen(3) strdup(3) memset(3) memcpy(3) +#include /* program_invocation_name program_invocation_short_name */ +#include /* os versions */ +#include /* freebsd setproctitle(3) */ +#include /* freebsd setproctitle(3) */ + +#if !defined(HAVE_SETPROCTITLE) +#if (__NetBSD__ || __FreeBSD__ || __OpenBSD__) +#define HAVE_SETPROCTITLE 1 +#if (__FreeBSD__ && __FreeBSD_version > 1200000) +#define HAVE_SETPROCTITLE_FAST 1 +#else +#define HAVE_SETPROCTITLE_FAST 0 +#endif +#else +#define HAVE_SETPROCTITLE 0 +#define HAVE_SETPROCTITLE_FAST 0 +#endif +#endif + + +#if HAVE_SETPROCTITLE +#define HAVE_SETPROCTITLE_REPLACEMENT 0 +#elif (defined __linux || defined __APPLE__) +#define HAVE_SETPROCTITLE_REPLACEMENT 1 +#else +#define HAVE_SETPROCTITLE_REPLACEMENT 0 +#endif + + +#if HAVE_SETPROCTITLE_REPLACEMENT + +#ifndef SPT_MAXTITLE +#define SPT_MAXTITLE 255 +#endif + + +extern char **environ; + + +static struct { + // Original value. + const char *arg0; + + // First enviroment variable. + char* env0; + + // Title space available. + char* base; + char* end; + + // Pointer to original nul character within base. + char *nul; + + int reset; +} SPT; + + +#ifndef SPT_MIN +#define SPT_MIN(a, b) (((a) < (b))? (a) : (b)) +#endif + + +static inline size_t spt_min(size_t a, size_t b) { + return SPT_MIN(a, b); +} + +static char **spt_find_argv_from_env(int argc, char *arg0) { + int i; + char **buf = NULL; + char *ptr; + char *limit; + + if (!(buf = (char **)malloc((argc + 1) * sizeof(char *)))) { + return NULL; + } + buf[argc] = NULL; + + // Walk back from environ until you find argc-1 null-terminated strings. + // Don't look for argv[0] as it's probably not preceded by 0. + ptr = SPT.env0; + limit = ptr - 8192; // TODO: empiric limit: should use MAX_ARG + --ptr; + for (i = argc - 1; i >= 1; --i) { + if (*ptr) { + return NULL; + } + --ptr; + while (*ptr && ptr > limit) { --ptr; } + if (ptr <= limit) { + return NULL; + } + buf[i] = (ptr + 1); + } + + // The first arg has not a zero in front. But what we have is reliable + // enough (modulo its encoding). Check if it is exactly what found. + // + // The check is known to fail on OS X with locale C if there are + // non-ascii characters in the executable path. + ptr -= strlen(arg0); + + if (ptr <= limit) { + return NULL; + } + if (strcmp(ptr, arg0)) { + return NULL; + } + + buf[0] = ptr; + return buf; +} + + +static int spt_init1() { + // Store a pointer to the first environment variable since go + // will overwrite environment. + SPT.env0 = environ[0]; + + return 2; +} + +static int spt_fast_init1() { + return 0; +} + + +static void spt_init2(int argc, char *arg0) { + char **argv = spt_find_argv_from_env(argc, arg0); + char **envp = &SPT.env0; + char *base, *end, *nul, *tmp; + int i; + + if (!argv) { + return; + } + + if (!(base = argv[0])) + return; + + nul = &base[strlen(base)]; + end = nul + 1; + + for (i = 0; i < argc || (i >= argc && argv[i]); i++) { + if (!argv[i] || argv[i] < end) + continue; + + end = argv[i] + strlen(argv[i]) + 1; + } + + for (i = 0; envp[i]; i++) { + if (envp[i] < end) + continue; + + end = envp[i] + strlen(envp[i]) + 1; + } + + if (!(SPT.arg0 = strdup(argv[0]))) + return; + +#if __GLIBC__ + if (!(tmp = strdup(program_invocation_name))) + return; + + program_invocation_name = tmp; + + if (!(tmp = strdup(program_invocation_short_name))) + return; + + program_invocation_short_name = tmp; +#elif __APPLE__ + if (!(tmp = strdup(getprogname()))) + return; + + setprogname(tmp); +#endif + + memset(base, 0, end - base); + + SPT.nul = nul; + SPT.base = base; + SPT.end = end; + + return; +} + + +static void setproctitle(const char *fmt, ...) { + char buf[SPT_MAXTITLE + 1]; // Use buffer in case argv[0] is passed. + va_list ap; + char *nul; + int len; + + if (!SPT.base) + return; + + if (fmt) { + va_start(ap, fmt); + len = vsnprintf(buf, sizeof buf, fmt, ap); + va_end(ap); + } else { + len = snprintf(buf, sizeof buf, "%s", SPT.arg0); + } + + if (len <= 0) { + return; + } + + if (!SPT.reset) { + memset(SPT.base, 0, SPT.end - SPT.base); + SPT.reset = 1; + } else { + memset(SPT.base, 0, spt_min(sizeof buf, SPT.end - SPT.base)); + } + + len = spt_min(len, spt_min(sizeof buf, SPT.end - SPT.base) - 1); + memcpy(SPT.base, buf, len); + nul = &SPT.base[len]; + + if (nul < SPT.nul) { + memset(nul, ' ', SPT.nul - nul); + } else if (nul == SPT.nul && &nul[1] < SPT.end) { + *SPT.nul = ' '; + *++nul = '\0'; + } +} + + +#else // HAVE_SETPROCTITLE_REPLACEMENT + +static int spt_init1() { +#if HAVE_SETPROCTITLE + return 1; +#else + return 0; +#endif +} + +static int spt_fast_init1() { +#if HAVE_SETPROCTITLE_FAST + return 1; +#else + return 0; +#endif +} + +static void spt_init2(int argc, char *arg0) { + (void)argc; + (void)arg0; +} + +#endif // HAVE_SETPROCTITLE_REPLACEMENT + + + +static void spt_setproctitle(const char *title) { +#if HAVE_SETPROCTITLE || HAVE_SETPROCTITLE_REPLACEMENT + setproctitle("%s", title); +#else + (void)title; +#endif +} + +static void spt_setproctitle_fast(const char *title) { +#if HAVE_SETPROCTITLE_FAST + setproctitle_fast("%s", title); +#else + (void)title; +#endif +} + diff --git a/vendor/modules.txt b/vendor/modules.txt index 74aaf294db..f1ac7ca9b7 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -422,6 +422,8 @@ github.com/dustin/go-humanize # github.com/emicklei/go-restful v2.9.5+incompatible github.com/emicklei/go-restful github.com/emicklei/go-restful/log +# github.com/erikdubbelboer/gspt v0.0.0-20190125194910-e68493906b83 +github.com/erikdubbelboer/gspt # github.com/euank/go-kmsg-parser v2.0.0+incompatible github.com/euank/go-kmsg-parser/kmsgparser # github.com/evanphx/json-patch v4.5.0+incompatible