diff mbox

mount.cifs: properly prune the capabilities bounding set

Message ID 1270480527-29726-1-git-send-email-jlayton@samba.org
State New
Headers show

Commit Message

Jeff Layton April 5, 2010, 3:15 p.m. UTC
...libcap-ng does this in a much easier fashion. If that's not
available, then we have to do it manually.

Signed-off-by: Jeff Layton <jlayton@samba.org>
---
 configure.ac |    3 +++
 mount.cifs.c |   37 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 39 insertions(+), 1 deletions(-)

Comments

Jeff Layton April 5, 2010, 3:26 p.m. UTC | #1
On Mon,  5 Apr 2010 11:15:26 -0400
Jeff Layton <jlayton@samba.org> wrote:

> ...libcap-ng does this in a much easier fashion. If that's not
> available, then we have to do it manually.
> 
> Signed-off-by: Jeff Layton <jlayton@samba.org>
> ---
>  configure.ac |    3 +++
>  mount.cifs.c |   37 ++++++++++++++++++++++++++++++++++++-
>  2 files changed, 39 insertions(+), 1 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index 857b0d8..d734d62 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -100,6 +100,9 @@ AC_FUNC_STRNLEN
>  # check for required functions
>  AC_CHECK_FUNCS([alarm atexit endpwent getmntent getpass gettimeofday inet_ntop memset realpath setenv strchr strdup strerror strncasecmp strndup strpbrk strrchr strstr strtol strtoul uname], , [AC_MSG_ERROR([necessary functions(s) not found])])
>  
> +# check for prctl
> +AC_CHECK_FUNCS([prctl])
> +
>  # ugly, but I'm not sure how to check for functions in a library that's not in $LIBS
>  cu_saved_libs=$LIBS
>  LIBS="$LIBS $KRB5_LDADD"
> diff --git a/mount.cifs.c b/mount.cifs.c
> index 1ff1846..712a8fe 100644
> --- a/mount.cifs.c
> +++ b/mount.cifs.c
> @@ -47,6 +47,9 @@
>  #ifdef HAVE_LIBCAP_NG
>  #include <cap-ng.h>
>  #else /* HAVE_LIBCAP_NG */
> +#ifdef HAVE_PRCTL
> +#include <sys/prctl.h>
> +#endif /* HAVE_PRCTL */
>  #ifdef HAVE_LIBCAP
>  #include <sys/capability.h>
>  #endif /* HAVE_LIBCAP */
> @@ -364,14 +367,46 @@ toggle_cap_dac_override(int enable)
>  	return 0;
>  }
>  #else /* HAVE_LIBCAP_NG */
> +#ifdef HAVE_PRCTL
> +static int
> +prune_bounding_set(void)
> +{
> +	int i, rc = 0;
> +	static int bounding_set_cleared;
> +
> +	if (bounding_set_cleared)
> +		return 0;
> +
> +	for (i = 0; i < CAP_LAST_CAP && rc == 0; ++i)
		     ^^^
	Self review here...

	That should be '<=' or we miss dropping the last capability in the list.

> +		rc = prctl(PR_CAPBSET_DROP, i);
> +
> +	if (rc != 0) {
> +		fprintf(stderr, "Unable to clear capability bounding set: %d\n", rc);
> +		return EX_SYSERR;
> +	}
> +
> +	++bounding_set_cleared;
> +	return 0;
> +}
> +#else /* HAVE_PRCTL */
> +static int
> +prune_bounding_set(void)
> +{
> +	return 0;
> +}
> +#endif /* HAVE_PRCTL */
>  #ifdef HAVE_LIBCAP
>  static int
>  drop_capabilities(int parent)
>  {
> -	int rc = 0, ncaps;
> +	int rc, ncaps;
>  	cap_t caps;
>  	cap_value_t cap_list[2];
>  
> +	rc = prune_bounding_set();
> +	if (rc)
> +		return rc;
> +
>  	caps = cap_get_proc();
>  	if (caps == NULL) {
>  		fprintf(stderr, "Unable to get current capability set: %s\n",
diff mbox

Patch

diff --git a/configure.ac b/configure.ac
index 857b0d8..d734d62 100644
--- a/configure.ac
+++ b/configure.ac
@@ -100,6 +100,9 @@  AC_FUNC_STRNLEN
 # check for required functions
 AC_CHECK_FUNCS([alarm atexit endpwent getmntent getpass gettimeofday inet_ntop memset realpath setenv strchr strdup strerror strncasecmp strndup strpbrk strrchr strstr strtol strtoul uname], , [AC_MSG_ERROR([necessary functions(s) not found])])
 
+# check for prctl
+AC_CHECK_FUNCS([prctl])
+
 # ugly, but I'm not sure how to check for functions in a library that's not in $LIBS
 cu_saved_libs=$LIBS
 LIBS="$LIBS $KRB5_LDADD"
diff --git a/mount.cifs.c b/mount.cifs.c
index 1ff1846..712a8fe 100644
--- a/mount.cifs.c
+++ b/mount.cifs.c
@@ -47,6 +47,9 @@ 
 #ifdef HAVE_LIBCAP_NG
 #include <cap-ng.h>
 #else /* HAVE_LIBCAP_NG */
+#ifdef HAVE_PRCTL
+#include <sys/prctl.h>
+#endif /* HAVE_PRCTL */
 #ifdef HAVE_LIBCAP
 #include <sys/capability.h>
 #endif /* HAVE_LIBCAP */
@@ -364,14 +367,46 @@  toggle_cap_dac_override(int enable)
 	return 0;
 }
 #else /* HAVE_LIBCAP_NG */
+#ifdef HAVE_PRCTL
+static int
+prune_bounding_set(void)
+{
+	int i, rc = 0;
+	static int bounding_set_cleared;
+
+	if (bounding_set_cleared)
+		return 0;
+
+	for (i = 0; i < CAP_LAST_CAP && rc == 0; ++i)
+		rc = prctl(PR_CAPBSET_DROP, i);
+
+	if (rc != 0) {
+		fprintf(stderr, "Unable to clear capability bounding set: %d\n", rc);
+		return EX_SYSERR;
+	}
+
+	++bounding_set_cleared;
+	return 0;
+}
+#else /* HAVE_PRCTL */
+static int
+prune_bounding_set(void)
+{
+	return 0;
+}
+#endif /* HAVE_PRCTL */
 #ifdef HAVE_LIBCAP
 static int
 drop_capabilities(int parent)
 {
-	int rc = 0, ncaps;
+	int rc, ncaps;
 	cap_t caps;
 	cap_value_t cap_list[2];
 
+	rc = prune_bounding_set();
+	if (rc)
+		return rc;
+
 	caps = cap_get_proc();
 	if (caps == NULL) {
 		fprintf(stderr, "Unable to get current capability set: %s\n",