Don't hard depend on capability.h and libcap

In the effort to make LXC work with non-standard Linux distros, this change
allows for the user to build LXC without capability support through a new
--disable-capabilities option to configure.

This effectively will cause LXC not to link against libcap and will turn all
the _cap_ functions into no-ops.

Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
This commit is contained in:
Stéphane Graber 2012-12-20 16:11:03 +01:00
parent e827ff7e2f
commit 495d2046f6
5 changed files with 70 additions and 13 deletions

View File

@ -180,17 +180,24 @@ AC_CHECK_HEADERS([linux/unistd.h linux/netlink.h linux/genetlink.h],
AC_MSG_ERROR([Please install the Linux kernel headers.]), AC_MSG_ERROR([Please install the Linux kernel headers.]),
[#include <sys/socket.h>]) [#include <sys/socket.h>])
# Allow disabling libcap support
AC_ARG_ENABLE([capabilities],
[AC_HELP_STRING([--disable-capabilities], [disable kernel capabilities])],
[], [enable_capabilities=yes])
# Check for libcap support # Check for libcap support
AC_CHECK_HEADERS([sys/capability.h], [], AC_MSG_ERROR([Please install the libcap development files.]), if test "x$enable_capabilities" = "xyes"; then
[#include <sys/types.h> AC_CHECK_LIB(cap,cap_set_proc,caplib=yes,caplib=no)
#include <sys/capability.h>]) AC_MSG_CHECKING([linux capabilities])
AC_CHECK_LIB(cap,cap_set_proc,caplib=yes,caplib=no) if test "x$caplib" = "xyes" ; then
AC_MSG_CHECKING([linux capabilities]) CAP_LIBS="-lcap"
if test "x$caplib" = "xyes" ; then AC_MSG_RESULT([$CAP_LIBS])
CAP_LIBS="-lcap" else
AC_MSG_RESULT([$CAP_LIBS]) AC_MSG_RESULT([no])
AC_MSG_ERROR([You are missing libcap support. If you really want to build without kernel capabilities, use --disable-capabilities])
fi
else else
AC_MSG_ERROR([not found]) CAP_LIBS=""
fi fi
AC_SUBST([CAP_LIBS]) AC_SUBST([CAP_LIBS])
@ -214,7 +221,7 @@ AM_CONDITIONAL([IS_BIONIC], [test "x$is_bionic" = "xyes"])
AC_CHECK_DECLS([PR_CAPBSET_DROP], [], [], [#include <sys/prctl.h>]) AC_CHECK_DECLS([PR_CAPBSET_DROP], [], [], [#include <sys/prctl.h>])
# Check for some headers # Check for some headers
AC_CHECK_HEADERS([sys/signalfd.h pty.h]) AC_CHECK_HEADERS([sys/signalfd.h pty.h sys/capability.h])
# Check for some functions # Check for some functions
AC_CHECK_FUNCS([openpty]) AC_CHECK_FUNCS([openpty])

View File

@ -27,13 +27,16 @@
#include <stdlib.h> #include <stdlib.h>
#include <limits.h> #include <limits.h>
#include <sys/prctl.h> #include <sys/prctl.h>
#include <sys/capability.h>
#include <errno.h> #include <errno.h>
#include "config.h"
#include "log.h" #include "log.h"
lxc_log_define(lxc_caps, lxc); lxc_log_define(lxc_caps, lxc);
#if HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
int lxc_caps_reset(void) int lxc_caps_reset(void)
{ {
cap_t cap = cap_init(); cap_t cap = cap_init();
@ -258,3 +261,4 @@ int lxc_caps_check(void)
return 1; return 1;
} }
#endif

View File

@ -20,9 +20,12 @@
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "config.h"
#ifndef _caps_h #ifndef _caps_h
#define _caps_h #define _caps_h
#if HAVE_SYS_CAPABILITY_H
extern int lxc_caps_reset(void); extern int lxc_caps_reset(void);
extern int lxc_caps_down(void); extern int lxc_caps_down(void);
extern int lxc_caps_up(void); extern int lxc_caps_up(void);
@ -30,6 +33,27 @@ extern int lxc_caps_init(void);
extern int lxc_caps_check(void); extern int lxc_caps_check(void);
extern int lxc_caps_last_cap(void); extern int lxc_caps_last_cap(void);
#else
static inline int lxc_caps_reset(void) {
return 0;
}
static inline int lxc_caps_down(void) {
return 0;
}
static inline int lxc_caps_up(void) {
return 0;
}
static inline int lxc_caps_init(void) {
return 0;
}
static inline int lxc_caps_check(void) {
return 1;
}
static inline int lxc_caps_last_cap(void) {
return 0;
}
#endif
#define lxc_priv(__lxc_function) \ #define lxc_priv(__lxc_function) \
({ \ ({ \

View File

@ -48,7 +48,6 @@
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/prctl.h> #include <sys/prctl.h>
#include <sys/capability.h>
#include <sys/personality.h> #include <sys/personality.h>
#include <arpa/inet.h> #include <arpa/inet.h>
@ -71,6 +70,10 @@
#include <apparmor.h> #include <apparmor.h>
#endif #endif
#if HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
#endif
#include "lxcseccomp.h" #include "lxcseccomp.h"
lxc_log_define(lxc_conf, lxc); lxc_log_define(lxc_conf, lxc);
@ -104,6 +107,7 @@ lxc_log_define(lxc_conf, lxc);
#define MS_STRICTATIME (1 << 24) #define MS_STRICTATIME (1 << 24)
#endif #endif
#if HAVE_SYS_CAPABILITY_H
#ifndef CAP_SETFCAP #ifndef CAP_SETFCAP
#define CAP_SETFCAP 31 #define CAP_SETFCAP 31
#endif #endif
@ -115,6 +119,7 @@ lxc_log_define(lxc_conf, lxc);
#ifndef CAP_MAC_ADMIN #ifndef CAP_MAC_ADMIN
#define CAP_MAC_ADMIN 33 #define CAP_MAC_ADMIN 33
#endif #endif
#endif
#ifndef PR_CAPBSET_DROP #ifndef PR_CAPBSET_DROP
#define PR_CAPBSET_DROP 24 #define PR_CAPBSET_DROP 24
@ -199,6 +204,7 @@ static struct mount_opt mount_opt[] = {
{ NULL, 0, 0 }, { NULL, 0, 0 },
}; };
#if HAVE_SYS_CAPABILITY_H
static struct caps_opt caps_opt[] = { static struct caps_opt caps_opt[] = {
{ "chown", CAP_CHOWN }, { "chown", CAP_CHOWN },
{ "dac_override", CAP_DAC_OVERRIDE }, { "dac_override", CAP_DAC_OVERRIDE },
@ -245,6 +251,9 @@ static struct caps_opt caps_opt[] = {
{ "wake_alarm", CAP_WAKE_ALARM }, { "wake_alarm", CAP_WAKE_ALARM },
#endif #endif
}; };
#else
static struct caps_opt caps_opt[] = {};
#endif
static int run_buffer(char *buffer) static int run_buffer(char *buffer)
{ {

View File

@ -41,12 +41,15 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/prctl.h> #include <sys/prctl.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/capability.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/un.h> #include <sys/un.h>
#include <sys/poll.h> #include <sys/poll.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#if HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
#endif
#ifdef HAVE_SYS_SIGNALFD_H #ifdef HAVE_SYS_SIGNALFD_H
# include <sys/signalfd.h> # include <sys/signalfd.h>
#else #else
@ -339,10 +342,14 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
} }
if (handler->conf->need_utmp_watch) { if (handler->conf->need_utmp_watch) {
#if HAVE_SYS_CAPABILITY_H
if (lxc_utmp_mainloop_add(&descr, handler)) { if (lxc_utmp_mainloop_add(&descr, handler)) {
ERROR("failed to add utmp handler to mainloop"); ERROR("failed to add utmp handler to mainloop");
goto out_mainloop_open; goto out_mainloop_open;
} }
#else
DEBUG("not starting utmp handler as cap_sys_boot cannot be dropped without capabilities support\n");
#endif
} }
return lxc_mainloop(&descr); return lxc_mainloop(&descr);
@ -553,6 +560,7 @@ static int do_start(void *data)
if (lxc_sync_barrier_parent(handler, LXC_SYNC_CONFIGURE)) if (lxc_sync_barrier_parent(handler, LXC_SYNC_CONFIGURE))
return -1; return -1;
#if HAVE_SYS_CAPABILITY_H
if (handler->conf->need_utmp_watch) { if (handler->conf->need_utmp_watch) {
if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0)) { if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0)) {
SYSERROR("failed to remove CAP_SYS_BOOT capability"); SYSERROR("failed to remove CAP_SYS_BOOT capability");
@ -560,6 +568,7 @@ static int do_start(void *data)
} }
DEBUG("Dropped cap_sys_boot\n"); DEBUG("Dropped cap_sys_boot\n");
} }
#endif
/* Setup the container, ip, names, utsname, ... */ /* Setup the container, ip, names, utsname, ... */
if (lxc_setup(handler->name, handler->conf)) { if (lxc_setup(handler->name, handler->conf)) {
@ -752,7 +761,11 @@ int __lxc_start(const char *name, struct lxc_conf *conf,
handler->data = data; handler->data = data;
if (must_drop_cap_sys_boot()) { if (must_drop_cap_sys_boot()) {
#if HAVE_SYS_CAPABILITY_H
DEBUG("Dropping cap_sys_boot\n"); DEBUG("Dropping cap_sys_boot\n");
#else
DEBUG("Can't drop cap_sys_boot as capabilities aren't supported\n");
#endif
} else { } else {
DEBUG("Not dropping cap_sys_boot or watching utmp\n"); DEBUG("Not dropping cap_sys_boot or watching utmp\n");
handler->conf->need_utmp_watch = 0; handler->conf->need_utmp_watch = 0;