mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-05 22:56:57 +02:00
MINOR: cli/debug: show dev: show capabilities
If haproxy compiled with Linux capabilities support, let's show process capabilities before applying the configuration and at runtime in 'show dev' command output. This maybe useful for debugging purposes. Especially in cases, when process changes its UID and GID to non-priviledged or it has started and run under non-priviledged UID and needed capabilities are set by admin on the haproxy binary.
This commit is contained in:
parent
0d79c9bedf
commit
2cd52a88be
@ -3,6 +3,8 @@
|
||||
#include <syscall.h>
|
||||
#include <linux/capability.h>
|
||||
|
||||
#define CAPS_TO_ULLONG(low, high) (((ullong)high << 32) | (ullong)low)
|
||||
|
||||
/* for haproxy process itself, allocate this 8 byte-size struct only once in
|
||||
* .data and makes it accessible from other compile-units, because we always
|
||||
* fill it with the same values and because we could use it to collect
|
||||
|
53
src/debug.c
53
src/debug.c
@ -38,6 +38,9 @@
|
||||
#include <haproxy/global.h>
|
||||
#include <haproxy/hlua.h>
|
||||
#include <haproxy/http_ana.h>
|
||||
#if defined(USE_LINUX_CAP)
|
||||
#include <haproxy/linuxcap.h>
|
||||
#endif
|
||||
#include <haproxy/log.h>
|
||||
#include <haproxy/net_helper.h>
|
||||
#include <haproxy/sc_strm.h>
|
||||
@ -113,6 +116,13 @@ struct post_mortem {
|
||||
pid_t pid;
|
||||
uid_t boot_uid;
|
||||
gid_t boot_gid;
|
||||
#if defined(USE_LINUX_CAP)
|
||||
struct {
|
||||
// initial process capabilities
|
||||
struct __user_cap_data_struct boot[_LINUX_CAPABILITY_U32S_3];
|
||||
int err; // errno, if capget() syscall fails
|
||||
} caps;
|
||||
#endif
|
||||
struct rlimit limit_fd; // RLIMIT_NOFILE
|
||||
struct rlimit limit_ram; // RLIMIT_DATA
|
||||
char **argv;
|
||||
@ -500,6 +510,10 @@ static int debug_parse_cli_show_libs(char **args, char *payload, struct appctx *
|
||||
/* parse a "show dev" command. It returns 1 if it emits anything otherwise zero. */
|
||||
static int debug_parse_cli_show_dev(char **args, char *payload, struct appctx *appctx, void *private)
|
||||
{
|
||||
#if defined(USE_LINUX_CAP)
|
||||
/* to dump runtime process capabilities */
|
||||
struct __user_cap_data_struct runtime_caps[_LINUX_CAPABILITY_U32S_3] = { };
|
||||
#endif
|
||||
const char **build_opt;
|
||||
int i;
|
||||
|
||||
@ -559,6 +573,41 @@ static int debug_parse_cli_show_dev(char **args, char *payload, struct appctx *a
|
||||
chunk_appendf(&trash, " boot gid: %d\n", post_mortem.process.boot_gid);
|
||||
chunk_appendf(&trash, " runtime gid: %d\n", getegid());
|
||||
|
||||
#if defined(USE_LINUX_CAP)
|
||||
/* let's dump saved in feed_post_mortem() initial capabilities sets */
|
||||
if(!post_mortem.process.caps.err) {
|
||||
chunk_appendf(&trash, " boot capabilities:\n");
|
||||
chunk_appendf(&trash, " \tCapEff: 0x%016llx\n",
|
||||
CAPS_TO_ULLONG(post_mortem.process.caps.boot[0].effective,
|
||||
post_mortem.process.caps.boot[1].effective));
|
||||
chunk_appendf(&trash, " \tCapPrm: 0x%016llx\n",
|
||||
CAPS_TO_ULLONG(post_mortem.process.caps.boot[0].permitted,
|
||||
post_mortem.process.caps.boot[1].permitted));
|
||||
chunk_appendf(&trash, " \tCapInh: 0x%016llx\n",
|
||||
CAPS_TO_ULLONG(post_mortem.process.caps.boot[0].inheritable,
|
||||
post_mortem.process.caps.boot[1].inheritable));
|
||||
} else
|
||||
chunk_appendf(&trash, " capget() failed with: %s.\n",
|
||||
strerror(post_mortem.process.caps.err));
|
||||
|
||||
|
||||
/* let's print actual capabilities sets, could be useful in order to compare */
|
||||
if (capget(&cap_hdr_haproxy, runtime_caps) == 0) {
|
||||
chunk_appendf(&trash, " runtime capabilities:\n");
|
||||
chunk_appendf(&trash, " \tCapEff: 0x%016llx\n",
|
||||
CAPS_TO_ULLONG(runtime_caps[0].effective,
|
||||
runtime_caps[1].effective));
|
||||
chunk_appendf(&trash, " \tCapPrm: 0x%016llx\n",
|
||||
CAPS_TO_ULLONG(runtime_caps[0].permitted,
|
||||
runtime_caps[1].permitted));
|
||||
chunk_appendf(&trash, " \tCapInh: 0x%016llx\n",
|
||||
CAPS_TO_ULLONG(runtime_caps[0].inheritable,
|
||||
runtime_caps[1].inheritable));
|
||||
} else
|
||||
chunk_appendf(&trash, " capget() failed with: %s.\n",
|
||||
strerror(errno));
|
||||
|
||||
#endif
|
||||
if ((ulong)post_mortem.process.limit_fd.rlim_cur != RLIM_INFINITY)
|
||||
chunk_appendf(&trash, " fd limit (soft): %lu\n", (ulong)post_mortem.process.limit_fd.rlim_cur);
|
||||
if ((ulong)post_mortem.process.limit_fd.rlim_max != RLIM_INFINITY)
|
||||
@ -2285,6 +2334,10 @@ static int feed_post_mortem()
|
||||
post_mortem.process.argc = global.argc;
|
||||
post_mortem.process.argv = global.argv;
|
||||
|
||||
#if defined(USE_LINUX_CAP)
|
||||
if (capget(&cap_hdr_haproxy, post_mortem.process.caps.boot) == -1)
|
||||
post_mortem.process.caps.err = errno;
|
||||
#endif
|
||||
getrlimit(RLIMIT_NOFILE, &post_mortem.process.limit_fd);
|
||||
getrlimit(RLIMIT_DATA, &post_mortem.process.limit_ram);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user