As we discussed off-line, Ben sent out a patch last year to drop most 
capabilities that was never merged:

        http://openvswitch.org/pipermail/dev/2014-July/042993.html

It may be worth looking at for comparison's sake.  There was a follow-up from 
Flavio that may be worth reading, too.

--Justin


> On Sep 14, 2015, at 3:54 PM, Andy Zhou <az...@nicira.com> wrote:
> 
> This patch adds an argument to daemon_become_new_user() API for the
> caller specify whether the capability of accessing the kernel datapath
> is needed. On Linux, daemons access the kernel datapath need to
> retain some root privileges, such as CAP_NET_ADMIN.
> 
> Current implementation (of retaining CAP_NET_ADMIN) requires libcap-ng.
> This implementation only covers the Linux.
> Other Unix platforms currently do not support kernel based datapath.
> (but supports --user options for all daemons.)
> On Windows, daemon_become_new_user() is a stub function that does
> nothing.
> 
> Signed-off-by: Andy Zhou <az...@nicira.com>
> ---
> lib/daemon-unix.c | 38 +++++++++++++++++++++++++++++++++++---
> lib/daemon.h      |  5 ++---
> 2 files changed, 37 insertions(+), 6 deletions(-)
> 
> diff --git a/lib/daemon-unix.c b/lib/daemon-unix.c
> index f175037..f361165 100644
> --- a/lib/daemon-unix.c
> +++ b/lib/daemon-unix.c
> @@ -27,6 +27,9 @@
> #include <sys/wait.h>
> #include <sys/stat.h>
> #include <unistd.h>
> +#if HAVE_LIBCAPNG
> +#include <cap-ng.h>
> +#endif
> #include "command-line.h"
> #include "fatal-signal.h"
> #include "dirs.h"
> @@ -748,8 +751,28 @@ daemon_switch_user(const uid_t real, const uid_t 
> effective, const uid_t saved,
>     }
> }
> 
> +static void
> +daemon_become_new_user_with_datapath_capability(void)
> +{
> +#if HAVE_LIBCAPNG
> +    if (capng_have_capabilities(CAPNG_SELECT_CAPS) > CAPNG_NONE) {
> +        capng_clear(CAPNG_SELECT_BOTH);
> +        capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
> +                     CAP_NET_ADMIN);
> +        if (capng_change_id(uid, gid,
> +                            CAPNG_DROP_SUPP_GRP | CAPNG_CLEAR_BOUNDING)) {
> +            VLOG_FATAL("%s: libcap-ng fail to switch to user and group "
> +                       "%d:%d, aborting", pidfile, uid, gid);
> +        }
> +    }
> +#else
> +    VLOG_FATAL("%s: fail to downgrade user using libcap-ng. (libcap-ng is "
> +               "not configured at compile time.) aborting", pidfile);
> +#endif
> +}
> +
> void
> -daemon_become_new_user(void)
> +daemon_become_new_user(bool access_kernel_datapath)
> {
>     /* "Setuid Demystified" by Hao Chen, etc outlines some caveats of
>      * around unix system call setuid() and friends. This implementation
> @@ -769,11 +792,20 @@ daemon_become_new_user(void)
>      * according to the paper above.)   */
> 
>     if (switch_to_new_user) {
> +
> +        if (access_kernel_datapath) {
> +            daemon_become_new_user_with_datapath_capability();
> +            return;
> +        }
> +
> +        /* Using more portable APIs to switch uid:gid, when datapath
> +         * access is not required.  On Linux systems, all capabilities
> +         * will be dropped.  */
>         daemon_switch_group(gid, gid, gid);
> 
>         if (user && initgroups(user, gid) == -1) {
> -            VLOG_FATAL("%s: fail to add supplementary group gid %d, 
> aborting",
> -                       pidfile, gid);
> +            VLOG_FATAL("%s: fail to add supplementary group gid %d, "
> +                       "aborting", pidfile, gid);
>         }
>         daemon_switch_user(uid, uid, uid, user);
>     }
> diff --git a/lib/daemon.h b/lib/daemon.h
> index fdd7b6a..f98ef16 100644
> --- a/lib/daemon.h
> +++ b/lib/daemon.h
> @@ -76,7 +76,7 @@ void set_detach(void);
> void daemon_set_monitor(void);
> void set_no_chdir(void);
> void ignore_existing_pidfile(void);
> -void daemon_become_new_user(void);
> +void daemon_become_new_user(bool access_kernel_datapath);
> pid_t read_pidfile(const char *name);
> #else
> #define DAEMON_OPTION_ENUMS                    \
> @@ -120,11 +120,10 @@ void control_handler(DWORD request);
> void set_pipe_handle(const char *pipe_handle);
> 
> static inline void
> -daemon_become_new_user(void)
> +daemon_become_new_user(bool access_kernel_datapath OVS_UNUSED)
> {
>     /* Not implemented. */
> }
> -
> #endif /* _WIN32 */
> 
> bool get_detach(void);
> -- 
> 1.9.1
> 
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to