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