@cryptotaxi247 / netdata-1 / commits / b42fab1df

apps.plugin now checks its capabilities where available

Costa Tsaousis (ktsaou) committed Jan 29, 2017 at 21:11 UTC b42fab1dffd41d693d614d5495097d875b528093
4 files changed +166 -49
configure.ac
+17
@@ -125,9 +125,14 @@ else
125 fi
126 fi
127
128 +AC_TYPE_INT8_T
129 +AC_TYPE_INT16_T
130 +AC_TYPE_INT32_T
131 +AC_TYPE_INT64_T
132 AC_TYPE_UINT8_T
133 AC_TYPE_UINT16_T
134 AC_TYPE_UINT32_T
135 +AC_TYPE_UINT64_T
136 AC_C_INLINE
137 AC_FUNC_STRERROR_R
138 AC_C__GENERIC
@@ -138,6 +143,17 @@ AC_CANONICAL_HOST
143 AC_HEADER_MAJOR
144 AC_HEADER_RESOLV
145
146 +AC_CHECK_LIB([cap], [cap_get_proc, cap_set_proc],
147 + [AC_CHECK_HEADER(
148 + [sys/capability.h],
149 + [
150 + CAP_LIBS=-lcap
151 + AC_DEFINE([HAVE_CAPABILITY], [1], [libcap usability])
152 + ]
153 + )]
154 +)
155 +OPTIONAL_CAP_LIBS="${CAP_LIBS}"
156 +
157 AC_ARG_VAR([SSE_CANDIDATE], [C compiler flags for SSE])
158 AS_CASE([$host_cpu],
159 [i?86], [SSE_CANDIDATE="yes"]
@@ -233,6 +249,7 @@ AC_SUBST([OPTIONAL_ZLIB_CLFAGS])
249 AC_SUBST([OPTIONAL_ZLIB_LIBS])
250 AC_SUBST([OPTIONAL_UUID_CLFAGS])
251 AC_SUBST([OPTIONAL_UUID_LIBS])
252 +AC_SUBST([OPTIONAL_CAP_LIBS])
253
254 AC_CONFIG_FILES([
255 Makefile
src/Makefile.am
+5
@@ -135,6 +135,11 @@ apps_plugin_SOURCES = \
135 web_buffer.c web_buffer.h \
136 $(NULL)
137
138 +apps_plugin_LDADD = \
139 + $(OPTIONAL_MATH_LIBS) \
140 + $(OPTIONAL_CAP_LIBS) \
141 + $(NULL)
142 +
143 install-data-hook:
144 if [ `id -u` == 0 ]; then \
145 chown root '$(DESTDIR)$(pluginsdir)/apps.plugin' && \
src/apps_plugin.c
+140 -49
@@ -354,6 +354,19 @@ static pid_t
354
355 #define FILE_DESCRIPTORS_INCREASE_STEP 100
356
357 +// types for struct file_descriptor->type
358 +typedef enum fd_filetype {
359 + FILETYPE_OTHER,
360 + FILETYPE_FILE,
361 + FILETYPE_PIPE,
362 + FILETYPE_SOCKET,
363 + FILETYPE_INOTIFY,
364 + FILETYPE_EVENTFD,
365 + FILETYPE_EVENTPOLL,
366 + FILETYPE_TIMERFD,
367 + FILETYPE_SIGNALFD
368 +} FD_FILETYPE;
369 +
370 struct file_descriptor {
371 avl avl;
372
@@ -364,7 +377,7 @@ struct file_descriptor {
377 const char *name;
378 uint32_t hash;
379
367 - char type;
380 + FD_FILETYPE type;
381 int count;
382 int pos;
383 } *all_files = NULL;
@@ -373,18 +386,6 @@ static int
386 all_files_len = 0,
387 all_files_size = 0;
388
376 -// types for struct file_descriptor->type
377 -#define FILETYPE_OTHER 0
378 -#define FILETYPE_FILE 1
379 -#define FILETYPE_PIPE 2
380 -#define FILETYPE_SOCKET 3
381 -#define FILETYPE_INOTIFY 4
382 -#define FILETYPE_EVENTFD 5
383 -#define FILETYPE_EVENTPOLL 6
384 -#define FILETYPE_TIMERFD 7
385 -#define FILETYPE_SIGNALFD 8
386 -
387 -
389 // ----------------------------------------------------------------------------
390 // callback required by fatal()
391
@@ -1179,7 +1180,7 @@ static inline void all_files_grow() {
1180 all_files_size += FILE_DESCRIPTORS_INCREASE_STEP;
1181 }
1182
1182 -static inline int file_descriptor_set_on_empty_slot(const char *name, uint32_t hash, int type) {
1183 +static inline int file_descriptor_set_on_empty_slot(const char *name, uint32_t hash, FD_FILETYPE type) {
1184 // check we have enough memory to add it
1185 if(!all_files || all_files_len == all_files_size)
1186 all_files_grow();
@@ -1260,7 +1261,7 @@ static inline int file_descriptor_find_or_add(const char *name)
1261 }
1262 // not found
1263
1263 - int type;
1264 + FD_FILETYPE type;
1265 if(name[0] == '/') type = FILETYPE_FILE;
1266 else if(strncmp(name, "pipe:", 5) == 0) type = FILETYPE_PIPE;
1267 else if(strncmp(name, "socket:", 7) == 0) type = FILETYPE_SOCKET;
@@ -2191,7 +2192,7 @@ static inline void aggregate_fd_on_target(int fd, struct target *w) {
2192 w->openeventpolls++;
2193 break;
2194
2194 - default:
2195 + case FILETYPE_OTHER:
2196 w->openother++;
2197 break;
2198 }
@@ -2387,6 +2388,42 @@ static usec_t send_resource_usage_to_netdata() {
2388 memmove(&me_last, &me, sizeof(struct rusage));
2389 }
2390
2391 + static char created_charts = 0;
2392 + if(unlikely(!created_charts)) {
2393 + created_charts = 1;
2394 +
2395 + fprintf(stdout
2396 + , "CHART netdata.apps_cpu '' 'Apps Plugin CPU' 'milliseconds/s' apps.plugin netdata.apps_cpu stacked 140000 %1$d\n"
2397 + "DIMENSION user '' incremental 1 1000\n"
2398 + "DIMENSION system '' incremental 1 1000\n"
2399 + "CHART netdata.apps_files '' 'Apps Plugin Files' 'files/s' apps.plugin netdata.apps_files line 140001 %1$d\n"
2400 + "DIMENSION files '' incremental 1 1\n"
2401 + "DIMENSION pids '' absolute 1 1\n"
2402 + "DIMENSION fds '' absolute 1 1\n"
2403 + "DIMENSION targets '' absolute 1 1\n"
2404 + "CHART netdata.apps_fix '' 'Apps Plugin Normalization Ratios' 'percentage' apps.plugin netdata.apps_fix line 140002 %1$d\n"
2405 + "DIMENSION utime '' absolute 1 %2$llu\n"
2406 + "DIMENSION stime '' absolute 1 %2$llu\n"
2407 + "DIMENSION gtime '' absolute 1 %2$llu\n"
2408 + "DIMENSION minflt '' absolute 1 %2$llu\n"
2409 + "DIMENSION majflt '' absolute 1 %2$llu\n"
2410 + , update_every
2411 + , RATES_DETAIL
2412 + );
2413 +
2414 + if(include_exited_childs)
2415 + fprintf(stdout
2416 + , "CHART netdata.apps_children_fix '' 'Apps Plugin Exited Children Normalization Ratios' 'percentage' apps.plugin netdata.apps_children_fix line 140003 %1$d\n"
2417 + "DIMENSION cutime '' absolute 1 %2$llu\n"
2418 + "DIMENSION cstime '' absolute 1 %2$llu\n"
2419 + "DIMENSION cgtime '' absolute 1 %2$llu\n"
2420 + "DIMENSION cminflt '' absolute 1 %2$llu\n"
2421 + "DIMENSION cmajflt '' absolute 1 %2$llu\n"
2422 + , update_every
2423 + , RATES_DETAIL
2424 + );
2425 + }
2426 +
2427 fprintf(stdout,
2428 "BEGIN netdata.apps_cpu %llu\n"
2429 "SET user = %llu\n"
@@ -2975,8 +3012,84 @@ static void parse_args(int argc, char **argv)
3012 }
3013 }
3014
2978 -int main(int argc, char **argv)
2979 -{
3015 +static int am_i_running_as_root() {
3016 + if(getuid() != 0) {
3017 + if(debug)
3018 + info("I am not running as root.");
3019 + return 0;
3020 + }
3021 +
3022 + if(debug)
3023 + info("I am running as root.");
3024 +
3025 + return 1;
3026 +}
3027 +
3028 +#ifdef HAVE_CAPABILITY
3029 +static int set_capabilities() {
3030 + if(!CAP_IS_SUPPORTED(CAP_DAC_READ_SEARCH)) {
3031 + error("This system does not support CAP_DAC_READ_SEARCH capability. Please setuid to root apps.plugin.");
3032 + return 0;
3033 + }
3034 + else if(debug)
3035 + info("System has CAP_DAC_READ_SEARCH capability.");
3036 +
3037 + if(!CAP_IS_SUPPORTED(CAP_SYS_PTRACE)) {
3038 + error("This system does not support CAP_SYS_PTRACE capability. Please setuid to root apps.plugin.");
3039 + return 0;
3040 + }
3041 + else if(debug)
3042 + info("System has CAP_SYS_PTRACE capability.");
3043 +
3044 + cap_t caps = cap_get_proc();
3045 + if(!caps) {
3046 + error("Cannot get current capabilities.");
3047 + return 0;
3048 + }
3049 + else if(debug)
3050 + info("Received my capabilities from the system.");
3051 +
3052 + int ret = 1;
3053 +
3054 + cap_flag_value_t cfv = CAP_CLEAR;
3055 + if(cap_get_flag(caps, CAP_DAC_READ_SEARCH, CAP_EFFECTIVE, &cfv) == -1) {
3056 + error("Cannot find if CAP_DAC_READ_SEARCH is effective.");
3057 + ret = 0;
3058 + }
3059 + else {
3060 + if(cfv != CAP_SET) {
3061 + error("apps.plugin should run with CAP_DAC_READ_SEARCH.");
3062 + ret = 0;
3063 + }
3064 + else if(debug)
3065 + info("apps.plugin runs with CAP_DAC_READ_SEARCH.");
3066 + }
3067 +
3068 + cfv = CAP_CLEAR;
3069 + if(cap_get_flag(caps, CAP_SYS_PTRACE, CAP_EFFECTIVE, &cfv) == -1) {
3070 + error("Cannot find if CAP_SYS_PTRACE is effective.");
3071 + ret = 0;
3072 + }
3073 + else {
3074 + if(cfv != CAP_SET) {
3075 + error("apps.plugin should run with CAP_SYS_PTRACE.");
3076 + ret = 0;
3077 + }
3078 + else if(debug)
3079 + info("apps.plugin runs with CAP_SYS_PTRACE.");
3080 + }
3081 +
3082 + cap_free(caps);
3083 +
3084 + return ret;
3085 +}
3086 +#else
3087 +static int check_capabilities() {
3088 + return 0;
3089 +}
3090 +#endif
3091 +
3092 +int main(int argc, char **argv) {
3093 // debug_flags = D_PROCFILE;
3094
3095 // set the name for logging
@@ -3023,40 +3136,18 @@ int main(int argc, char **argv)
3136
3137 parse_args(argc, argv);
3138
3139 + if(!am_i_running_as_root())
3140 + if(!set_capabilities())
3141 + error("apps.plugin should either run as root or have special capabilities. "
3142 + "Without these, apps.plugin cannot report disk I/O utilization of other processes. "
3143 + "To enable capabilities run: sudo setcap cap_dac_read_search,cap_sys_ptrace+ep %1$s; "
3144 + "To enable setuid to root run: sudo chown root %1$s; sudo chmod 4755 %1$s; "
3145 + , argv[0]
3146 + );
3147 +
3148 all_pids_sortlist = callocz(sizeof(pid_t), (size_t)pid_max);
3149 all_pids = callocz(sizeof(struct pid_stat *), (size_t) pid_max);
3150
3029 - fprintf(stdout,
3030 - "CHART netdata.apps_cpu '' 'Apps Plugin CPU' 'milliseconds/s' apps.plugin netdata.apps_cpu stacked 140000 %1$d\n"
3031 - "DIMENSION user '' incremental 1 1000\n"
3032 - "DIMENSION system '' incremental 1 1000\n"
3033 - "CHART netdata.apps_files '' 'Apps Plugin Files' 'files/s' apps.plugin netdata.apps_files line 140001 %1$d\n"
3034 - "DIMENSION files '' incremental 1 1\n"
3035 - "DIMENSION pids '' absolute 1 1\n"
3036 - "DIMENSION fds '' absolute 1 1\n"
3037 - "DIMENSION targets '' absolute 1 1\n"
3038 - "CHART netdata.apps_fix '' 'Apps Plugin Normalization Ratios' 'percentage' apps.plugin netdata.apps_fix line 140002 %1$d\n"
3039 - "DIMENSION utime '' absolute 1 %2$llu\n"
3040 - "DIMENSION stime '' absolute 1 %2$llu\n"
3041 - "DIMENSION gtime '' absolute 1 %2$llu\n"
3042 - "DIMENSION minflt '' absolute 1 %2$llu\n"
3043 - "DIMENSION majflt '' absolute 1 %2$llu\n"
3044 - , update_every
3045 - , RATES_DETAIL
3046 - );
3047 -
3048 - if(include_exited_childs)
3049 - fprintf(stdout,
3050 - "CHART netdata.apps_children_fix '' 'Apps Plugin Exited Children Normalization Ratios' 'percentage' apps.plugin netdata.apps_children_fix line 140003 %1$d\n"
3051 - "DIMENSION cutime '' absolute 1 %2$llu\n"
3052 - "DIMENSION cstime '' absolute 1 %2$llu\n"
3053 - "DIMENSION cgtime '' absolute 1 %2$llu\n"
3054 - "DIMENSION cminflt '' absolute 1 %2$llu\n"
3055 - "DIMENSION cmajflt '' absolute 1 %2$llu\n"
3056 - , update_every
3057 - , RATES_DETAIL
3058 - );
3059 -
3151 usec_t step = update_every * USEC_PER_SEC;
3152 global_iterations_counter = 1;
3153 heartbeat_t hb;
src/common.h
+4
@@ -109,6 +109,10 @@
109 #include <zlib.h>
110 #endif
111
112 +#ifdef HAVE_CAPABILITY
113 +#include <sys/capability.h>
114 +#endif
115 +
116 // ----------------------------------------------------------------------------
117 // netdata common definitions
118