From: Florian Forster Date: Fri, 28 Oct 2016 13:04:11 +0000 (+0200) Subject: src/daemon/common.c: Rewrite check_capability() using cap_get_bound(). X-Git-Tag: collectd-5.6.2~14 X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=58acba67f2a814698e7ebef1c00ec35fa21ef740 src/daemon/common.c: Rewrite check_capability() using cap_get_bound(). capget(2) is Linux specific and the use of the raw syscalls is discouraged. Also, there have been interesting crashes on some systems. Issue: #2009 --- diff --git a/configure.ac b/configure.ac index 9a6da11d..4ccb893c 100644 --- a/configure.ac +++ b/configure.ac @@ -808,7 +808,20 @@ fi have_cpuid_h="no" AC_CHECK_HEADERS(cpuid.h, [have_cpuid_h="yes"]) -AC_CHECK_HEADERS(sys/capability.h) +have_capability="yes" +AC_CHECK_HEADERS(sys/capability.h, + [have_capability="yes"], + [have_capability="no ( not found)"]) +if test "x$have_capability" = "xyes"; then +AC_CHECK_LIB(cap, cap_get_bound, + [have_capability="yes"], + [have_capability="no (cap_get_bound() not found)"]) +fi +if test "x$have_capability" = "xyes"; then + AC_DEFINE(HAVE_CAPABILITY, 1, [Define to 1 if you have cap_get_bound() (-lcap).]) +fi +AM_CONDITIONAL(BUILD_WITH_CAPABILITY, test "x$have_capability" = "xyes") + # # Checks for typedefs, structures, and compiler characteristics. # diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am index 632872a2..cb62c645 100644 --- a/src/daemon/Makefile.am +++ b/src/daemon/Makefile.am @@ -11,6 +11,9 @@ AM_CPPFLAGS += -DPKGDATADIR='"${pkgdatadir}"' # Link to these libraries.. COMMON_LIBS = $(PTHREAD_LIBS) +if BUILD_WITH_CAPABILITY +COMMON_LIBS += -lcap +endif if BUILD_WITH_LIBRT COMMON_LIBS += -lrt endif diff --git a/src/daemon/common.c b/src/daemon/common.c index 477d7599..212d72c9 100644 --- a/src/daemon/common.c +++ b/src/daemon/common.c @@ -60,7 +60,7 @@ # include #endif -#ifdef HAVE_SYS_CAPABILITY_H +#if HAVE_CAPABILITY # include #endif @@ -1678,51 +1678,25 @@ void strarray_free (char **array, size_t array_len) /* {{{ */ sfree (array); } /* }}} void strarray_free */ -#ifdef HAVE_SYS_CAPABILITY_H -int check_capability (int capability) /* {{{ */ +#if HAVE_CAPABILITY +int check_capability (int arg) /* {{{ */ { -#ifdef _LINUX_CAPABILITY_VERSION_3 - cap_user_header_t cap_header = calloc(1, sizeof (*cap_header)); - if (cap_header == NULL) - { - ERROR("check_capability: calloc failed"); - return (-1); - } + cap_value_t cap = (cap_value_t) arg; - cap_user_data_t cap_data = calloc(1, sizeof (*cap_data)); - if (cap_data == NULL) - { - ERROR("check_capability: calloc failed"); - sfree(cap_header); + if (!CAP_IS_SUPPORTED (cap)) return (-1); - } - cap_header->pid = getpid(); - cap_header->version = _LINUX_CAPABILITY_VERSION_3; - if (capget(cap_header, cap_data) < 0) - { - ERROR("check_capability: capget failed"); - sfree(cap_header); - sfree(cap_data); + int have_cap = cap_get_bound (cap); + if (have_cap != 1) return (-1); - } - if ((cap_data->effective & (1 << capability)) == 0) - { - sfree(cap_header); - sfree(cap_data); - return (-1); - } - else - { - sfree(cap_header); - sfree(cap_data); - return (0); - } + return (0); +} /* }}} int check_capability */ #else +int check_capability (__attribute__((unused)) int arg) /* {{{ */ +{ WARNING ("check_capability: unsupported capability implementation. " - "Some plugin(s) may require elevated privileges to work properly."); + "Some plugin(s) may require elevated privileges to work properly."); return (0); -#endif /* _LINUX_CAPABILITY_VERSION_3 */ } /* }}} int check_capability */ -#endif /* HAVE_SYS_CAPABILITY_H */ +#endif /* HAVE_CAPABILITY */