This is an automated email from the git hooks/post-receive script.
rharwood pushed a change to branch master in repository gssproxy.
from 1aff8e4 Fix typo about pid-file new 2ca4525 Retain CAP_SYS_PTRACE when running as unpriviliged new f03d9b7 Make build with capabilities optional new 9e38cd5 Move run_as_user check out of drop_privs()
The 3 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "add" were already present in the repository and have only been added to this reference.
Summary of changes: Makefile.am | 4 ++ conf_macros.m4 | 17 +++++ configure.ac | 10 +++ contrib/gssproxy.spec.in | 1 + src/gp_init.c | 178 ++++++++++++++++++++++++++++++++++++++++++++--- src/gp_proxy.h | 4 ++ src/gssproxy.c | 12 ++-- 7 files changed, 211 insertions(+), 15 deletions(-)
This is an automated email from the git hooks/post-receive script.
rharwood pushed a commit to branch master in repository gssproxy.
commit 2ca452537b29cc04ea5248db6328b2ddf948db15 Author: Stanislav Levin slev@altlinux.org AuthorDate: Fri Dec 7 10:29:20 2018 +0300
Retain CAP_SYS_PTRACE when running as unpriviliged
Without CAP_SYS_PTRACE, gssproxy will be unable to read /proc/pid/exe, which breaks program name matching.
Fixes: https://pagure.io/gssproxy/issue/239 Signed-off-by: Stanislav Levin slev@altlinux.org [rharwood@redhat.com: rewrite commit message, comments, and error strings] Reviewed-by: Robbie Harwood rharwood@redhat.com Reviewed-by: Simo Sorce simo@redhat.com Merges: #240 --- Makefile.am | 2 +- configure.ac | 7 ++ contrib/gssproxy.spec.in | 1 + src/gp_init.c | 164 ++++++++++++++++++++++++++++++++++++++++++++--- src/gp_proxy.h | 2 + 5 files changed, 167 insertions(+), 9 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 5f3aeb0..3595963 100644 --- a/Makefile.am +++ b/Makefile.am @@ -88,7 +88,7 @@ AM_CPPFLAGS += \ -DSYSCONFDIR="$(sysconfdir)" \ -DLOCALEDIR="$(localedir)"
-GSS_PROXY_LIBS = $(POPT_LIBS) $(KRB5_LIBS) $(VERTO_LIBS) $(INI_LIBS) $(GSSAPI_LIBS) $(GSSRPC_LIBS) +GSS_PROXY_LIBS = $(POPT_LIBS) $(KRB5_LIBS) $(VERTO_LIBS) $(INI_LIBS) $(GSSAPI_LIBS) $(GSSRPC_LIBS) $(CAP_LIBS)
if BUILD_SELINUX GSS_PROXY_LIBS += $(SELINUX_LIBS) diff --git a/configure.ac b/configure.ac index 0af44ab..a7f6aaf 100644 --- a/configure.ac +++ b/configure.ac @@ -280,6 +280,13 @@ AC_CHECK_LIB(gssrpc, gssrpc_xdrmem_create,, [$GSSAPI_LIBS $GSSRPC_LIBS]) AC_SUBST([GSSRPC_LIBS])
+AC_CHECK_FUNC([prctl],,[AC_MSG_ERROR([Failed to find prctl])]) +AC_CHECK_LIB([cap], [cap_set_proc],[CAP_LIBS=-lcap], + [AC_MSG_ERROR(["Failed to find libcap symbols"])]) +AC_SUBST([CAP_LIBS]) +AC_CHECK_HEADERS([sys/capability.h],, + [AC_MSG_ERROR([Could not find libcap headers])]) + AC_CHECK_FUNCS([__secure_getenv secure_getenv])
WITH_INITSCRIPT diff --git a/contrib/gssproxy.spec.in b/contrib/gssproxy.spec.in index ccd3e50..3ce7113 100644 --- a/contrib/gssproxy.spec.in +++ b/contrib/gssproxy.spec.in @@ -40,6 +40,7 @@ BuildRequires: libselinux-devel BuildRequires: keyutils-libs-devel BuildRequires: libini_config-devel >= 1.2.0 BuildRequires: libverto-devel +BuildRequires: libcap-devel BuildRequires: popt-devel BuildRequires: findutils BuildRequires: systemd-units diff --git a/src/gp_init.c b/src/gp_init.c index f64e22c..47a461c 100644 --- a/src/gp_init.c +++ b/src/gp_init.c @@ -1,17 +1,21 @@ /* Copyright (C) 2011,2015 the GSS-PROXY contributors, see COPYING for license */
-#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> +#include <errno.h> +#include <fcntl.h> +#include <grp.h> +#include <linux/capability.h> #include <locale.h> +#include <pwd.h> #include <signal.h> -#include <fcntl.h> -#include <errno.h> +#include <stdio.h> +#include <stdlib.h> #include <string.h> +#include <sys/capability.h> +#include <sys/prctl.h> +#include <sys/stat.h> +#include <sys/types.h> #include <unistd.h> -#include <stdio.h> -#include <pwd.h> -#include <grp.h> + #include "gp_proxy.h"
void init_server(bool daemonize, int *wait_fd) @@ -223,6 +227,16 @@ int drop_privs(struct gp_config *cfg) return 0; }
+ /* Retain capabilities when changing UID to non-zero. We drop the ones we + * don't need after the switch. */ + ret = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); + if (ret) { + ret = errno; + GPDEBUG("Failed to set keep capabilities: [%d:%s]\n", + ret, gp_strerror(ret)); + return ret; + } + ret = getpwnam_r(cfg->proxy_user, &pws, buf, 2048, &pw); if (ret) { GPDEBUG("Failed to look up proxy user: '%s'! [%d:%s]\n", @@ -253,5 +267,139 @@ int drop_privs(struct gp_config *cfg) return ret; }
+ /* Now drop the capabilities we don't need, and turn PR_SET_KEEPCAPS back + * off. */ + ret = drop_caps(); + if (ret) { + return ret; + } + + if (prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0)) { + ret = errno; + GPDEBUG("Failed to reset keep capabilities: [%d:%s]\n", + ret, gp_strerror(ret)); + return ret; + } + return 0; } + +/* Remove all capabilties from the process. (In order to manipulate our + * capability set, we need to have CAP_SETPCAP.) */ +int clear_bound_caps() +{ + cap_t caps = NULL; + cap_value_t cap = 0; + const cap_value_t setpcap_list[] = { CAP_SETPCAP }; + int ret; + + caps = cap_get_proc(); + if (caps == NULL) { + ret = errno; + GPDEBUG("Failed to get current capabilities: [%d:%s]\n", + ret, gp_strerror(ret)); + goto done; + } + + if (cap_set_flag(caps, CAP_EFFECTIVE, 1, setpcap_list, CAP_SET) == -1) { + ret = errno; + GPDEBUG("Failed to set CAP_SETPCAP in effective set: [%d:%s]\n", ret, + gp_strerror(ret)); + goto done; + } + + if (cap_set_proc(caps) == -1) { + ret = errno; + GPDEBUG("Failed to apply CAP_SETPCAP: [%d:%s]\n", ret, + gp_strerror(ret)); + goto done; + } + + /* Now that we have CAP_SETPCAP in the effective set, remove all other + * capabilities. */ + while (CAP_IS_SUPPORTED(cap)) { + if (cap_drop_bound(cap) != 0) { + ret = errno; + GPDEBUG("Failed to drop bounding set capability: [%d:%s]\n", + ret, gp_strerror(ret)); + goto done; + } + cap++; + } + ret = 0; + +done: + if (caps && cap_free(caps) == -1) { + ret = errno; + GPDEBUG("Failed to free capability state: [%d:%s]\n", + ret, gp_strerror(ret)); + } + return ret; +} + +/* For program name matching, we need to have CAP_SYS_PTRACE in order to read + * /proc/pid/exe. Because we've set PR_SET_KEEPCAPS, every thread inherits + * the process set of its parent, so we drop everything but CAP_SYS_PTRACE. */ +int drop_caps() +{ + cap_t caps = NULL; + int ret; + const cap_value_t ptrace_list[] = { CAP_SYS_PTRACE }; + + /* Completely drop the bounding set. */ + ret = clear_bound_caps(); + if (ret) { + goto done; + } + + ret = CAP_IS_SUPPORTED(CAP_SYS_PTRACE); + if (ret == -1) { + ret = errno; + GPDEBUG("Failed to check if CAP_SYS_PTRACE is supported: [%d:%s]\n", + ret, gp_strerror(ret)); + goto done; + } else if (!ret) { + GPDEBUG("Capability CAPS_SYS_PTRACE is not supported\n"); + ret = EINVAL; + goto done; + } + + /* Now, make an empty capabilitiy set and put CAP_SYS_PTRACE in it. */ + caps = cap_init(); + if (caps == NULL) { + ret = errno; + GPDEBUG("Failed to init capabilities: [%d:%s]\n", + ret, gp_strerror(ret)); + goto done; + } + + if (cap_set_flag(caps, CAP_PERMITTED, 1, ptrace_list, CAP_SET) == -1) { + ret = errno; + GPDEBUG("Failed to set permitted capabilities: [%d:%s]\n", + ret, gp_strerror(ret)); + goto done; + } + + if (cap_set_flag(caps, CAP_EFFECTIVE, 1, ptrace_list, CAP_SET) == -1) { + ret = errno; + GPDEBUG("Failed to set effective capabilities: [%d:%s]\n", + ret, gp_strerror(ret)); + goto done; + } + + if (cap_set_proc(caps) == -1) { + ret = errno; + GPDEBUG("Failed to apply capability set: [%d:%s]\n", + ret, gp_strerror(ret)); + goto done; + } + ret = 0; + +done: + if (caps && cap_free(caps) == -1) { + ret = errno; + GPDEBUG("Failed to free capability state: [%d:%s]\n", + ret, gp_strerror(ret)); + } + return ret; +} diff --git a/src/gp_proxy.h b/src/gp_proxy.h index 3e944ab..8763bcf 100644 --- a/src/gp_proxy.h +++ b/src/gp_proxy.h @@ -102,6 +102,8 @@ verto_ctx *init_event_loop(void); void init_proc_nfsd(struct gp_config *cfg); void write_pid(void); int drop_privs(struct gp_config *cfg); +int drop_caps(void); +int clear_bound_caps(void);
/* from gp_socket.c */ void free_unix_socket(verto_ctx *ctx, verto_ev *ev);
This is an automated email from the git hooks/post-receive script.
rharwood pushed a commit to branch master in repository gssproxy.
commit f03d9b7451781877053cd0ebcb9ace1ba64176e6 Author: Stanislav Levin slev@altlinux.org AuthorDate: Sat Dec 29 11:56:30 2018 +0300
Make build with capabilities optional
Fixes: https://pagure.io/gssproxy/issue/239 Signed-off-by: Stanislav Levin slev@altlinux.org [rharwood@redhat.com: rebase, commit message] Reviewed-by: Robbie Harwood rharwood@redhat.com Reviewed-by: Simo Sorce simo@redhat.com --- Makefile.am | 6 +++++- conf_macros.m4 | 17 +++++++++++++++++ configure.ac | 15 +++++++++------ src/gp_init.c | 19 ++++++++++++++++--- src/gp_proxy.h | 2 ++ 5 files changed, 49 insertions(+), 10 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 3595963..408391d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -88,12 +88,16 @@ AM_CPPFLAGS += \ -DSYSCONFDIR="$(sysconfdir)" \ -DLOCALEDIR="$(localedir)"
-GSS_PROXY_LIBS = $(POPT_LIBS) $(KRB5_LIBS) $(VERTO_LIBS) $(INI_LIBS) $(GSSAPI_LIBS) $(GSSRPC_LIBS) $(CAP_LIBS) +GSS_PROXY_LIBS = $(POPT_LIBS) $(KRB5_LIBS) $(VERTO_LIBS) $(INI_LIBS) $(GSSAPI_LIBS) $(GSSRPC_LIBS)
if BUILD_SELINUX GSS_PROXY_LIBS += $(SELINUX_LIBS) endif
+if HAVE_CAP + GSS_PROXY_LIBS += $(CAP_LIBS) +endif + GP_RPCGEN_OBJ = rpcgen/gp_rpc_xdr.c rpcgen/gss_proxy_xdr.c rpcgen/gp_xdr.c GP_RPCCLI_OBJ = \ src/client/gpm_display_status.c \ diff --git a/conf_macros.m4 b/conf_macros.m4 index ceb46a7..d81792b 100644 --- a/conf_macros.m4 +++ b/conf_macros.m4 @@ -274,3 +274,20 @@ AC_DEFUN([WITH_HARDENING], ) AM_CONDITIONAL([BUILD_HARDENING], [test x"$with_hardening" = xyes]) ]) + +AC_DEFUN([WITH_CAP], + [ AC_ARG_WITH([cap], + [AC_HELP_STRING([--with-cap], + [Whether to build with libcap [no]] + ) + ], + [], + with_cap=no + ) + if test x"$with_cap" = xyes; then + HAVE_CAP=1 + AC_SUBST(HAVE_CAP) + AC_DEFINE_UNQUOTED([HAVE_CAP], [1], [Build with capabilities support]) + fi + ]) +AM_CONDITIONAL([HAVE_CAP], [test x$with_cap = xyes]) diff --git a/configure.ac b/configure.ac index a7f6aaf..4fbe5bf 100644 --- a/configure.ac +++ b/configure.ac @@ -280,12 +280,15 @@ AC_CHECK_LIB(gssrpc, gssrpc_xdrmem_create,, [$GSSAPI_LIBS $GSSRPC_LIBS]) AC_SUBST([GSSRPC_LIBS])
-AC_CHECK_FUNC([prctl],,[AC_MSG_ERROR([Failed to find prctl])]) -AC_CHECK_LIB([cap], [cap_set_proc],[CAP_LIBS=-lcap], - [AC_MSG_ERROR(["Failed to find libcap symbols"])]) -AC_SUBST([CAP_LIBS]) -AC_CHECK_HEADERS([sys/capability.h],, - [AC_MSG_ERROR([Could not find libcap headers])]) +WITH_CAP +if test x$HAVE_CAP != x; then + AC_CHECK_FUNC([prctl],,[AC_MSG_ERROR([Failed to find prctl])]) + AC_CHECK_LIB([cap], [cap_set_proc],[CAP_LIBS=-lcap], + [AC_MSG_ERROR(["Failed to find libcap symbols"])]) + AC_SUBST([CAP_LIBS]) + AC_CHECK_HEADERS([sys/capability.h],, + [AC_MSG_ERROR([Could not find libcap headers])]) +fi
AC_CHECK_FUNCS([__secure_getenv secure_getenv])
diff --git a/src/gp_init.c b/src/gp_init.c index 47a461c..6dc2398 100644 --- a/src/gp_init.c +++ b/src/gp_init.c @@ -1,21 +1,28 @@ /* Copyright (C) 2011,2015 the GSS-PROXY contributors, see COPYING for license */
+#include <config.h> + #include <errno.h> #include <fcntl.h> #include <grp.h> -#include <linux/capability.h> #include <locale.h> #include <pwd.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <sys/capability.h> -#include <sys/prctl.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h>
+#ifdef HAVE_CAP + +#include <linux/capability.h> +#include <sys/capability.h> +#include <sys/prctl.h> + +#endif + #include "gp_proxy.h"
void init_server(bool daemonize, int *wait_fd) @@ -227,6 +234,7 @@ int drop_privs(struct gp_config *cfg) return 0; }
+#ifdef HAVE_CAP /* Retain capabilities when changing UID to non-zero. We drop the ones we * don't need after the switch. */ ret = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); @@ -236,6 +244,7 @@ int drop_privs(struct gp_config *cfg) ret, gp_strerror(ret)); return ret; } +#endif
ret = getpwnam_r(cfg->proxy_user, &pws, buf, 2048, &pw); if (ret) { @@ -267,6 +276,7 @@ int drop_privs(struct gp_config *cfg) return ret; }
+#ifdef HAVE_CAP /* Now drop the capabilities we don't need, and turn PR_SET_KEEPCAPS back * off. */ ret = drop_caps(); @@ -280,10 +290,12 @@ int drop_privs(struct gp_config *cfg) ret, gp_strerror(ret)); return ret; } +#endif
return 0; }
+#ifdef HAVE_CAP /* Remove all capabilties from the process. (In order to manipulate our * capability set, we need to have CAP_SETPCAP.) */ int clear_bound_caps() @@ -403,3 +415,4 @@ done: } return ret; } +#endif diff --git a/src/gp_proxy.h b/src/gp_proxy.h index 8763bcf..8ccb5ab 100644 --- a/src/gp_proxy.h +++ b/src/gp_proxy.h @@ -102,8 +102,10 @@ verto_ctx *init_event_loop(void); void init_proc_nfsd(struct gp_config *cfg); void write_pid(void); int drop_privs(struct gp_config *cfg); +#ifdef HAVE_CAP int drop_caps(void); int clear_bound_caps(void); +#endif
/* from gp_socket.c */ void free_unix_socket(verto_ctx *ctx, verto_ev *ev);
This is an automated email from the git hooks/post-receive script.
rharwood pushed a commit to branch master in repository gssproxy.
commit 9e38cd56177eefd54880eb4e92f63ee362e74f61 Author: Stanislav Levin slev@altlinux.org AuthorDate: Sat Dec 29 12:08:26 2018 +0300
Move run_as_user check out of drop_privs()
Signed-off-by: Stanislav Levin slev@altlinux.org [rharwood@redhat.com: commit message] Reviewed-by: Robbie Harwood rharwood@redhat.com Reviewed-by: Simo Sorce simo@redhat.com --- src/gp_init.c | 5 ----- src/gssproxy.c | 12 ++++++++---- 2 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/src/gp_init.c b/src/gp_init.c index 6dc2398..24839de 100644 --- a/src/gp_init.c +++ b/src/gp_init.c @@ -229,11 +229,6 @@ int drop_privs(struct gp_config *cfg) struct passwd *pw, pws; int ret;
- if (cfg->proxy_user == NULL) { - /* not dropping privs */ - return 0; - } - #ifdef HAVE_CAP /* Retain capabilities when changing UID to non-zero. We drop the ones we * don't need after the switch. */ diff --git a/src/gssproxy.c b/src/gssproxy.c index 93c1c1e..01d4ef9 100644 --- a/src/gssproxy.c +++ b/src/gssproxy.c @@ -269,10 +269,14 @@ int main(int argc, const char *argv[]) * so it can continue with dependencies and start nfsd */ init_done(wait_fd);
- ret = drop_privs(gpctx->config); - if (ret) { - ret = EXIT_FAILURE; - goto cleanup; + /* if config option "run_as_user" is missing, then it's no need to + * drop privileges */ + if (gpctx->config->proxy_user) { + ret = drop_privs(gpctx->config); + if (ret) { + ret = EXIT_FAILURE; + goto cleanup; + } }
ret = gp_workers_init(gpctx);
gss-proxy@lists.fedorahosted.org