public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Peter Volkov (pva)" <pva@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] gentoo-x86 commit in net-analyzer/wireshark/files: wireshark-1.0.0_rc1-fix-stop-capture.patch wireshark-1.0.0_rc1-fix-setcap-EPERM.patch
Date: Sun, 23 Mar 2008 14:06:29 +0000	[thread overview]
Message-ID: <E1JdQqD-0003VO-Ec@stork.gentoo.org> (raw)

pva         08/03/23 14:06:29

  Added:                wireshark-1.0.0_rc1-fix-stop-capture.patch
                        wireshark-1.0.0_rc1-fix-setcap-EPERM.patch
  Log:
  Fix wireshark stop when built with caps.
  (Portage version: 2.1.4.4)

Revision  Changes    Path
1.1                  net-analyzer/wireshark/files/wireshark-1.0.0_rc1-fix-stop-capture.patch

file : http://sources.gentoo.org/viewcvs.py/gentoo-x86/net-analyzer/wireshark/files/wireshark-1.0.0_rc1-fix-stop-capture.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewcvs.py/gentoo-x86/net-analyzer/wireshark/files/wireshark-1.0.0_rc1-fix-stop-capture.patch?rev=1.1&content-type=text/plain

Index: wireshark-1.0.0_rc1-fix-stop-capture.patch
===================================================================
Author: 	wmeier
Date: 	Sat Mar 22 19:04:26 2008 UTC (16 hours, 26 minutes ago)
Log Message: 	

Fix (aka workaround) for bug #2228.  Essentially: if using libcap, drop
capabilities after doing pcap_open_live.  See comment in main() for details.

--- trunk/dumpcap.c	2008/03/22 05:50:19	24715
+++ trunk/dumpcap.c	2008/03/22 19:04:26	24716
@@ -102,8 +102,8 @@
  */
 #include "wiretap/libpcap.h"
 
-/*#define DEBUG_DUMPCAP*/
-/*#define DEBUG_CHILD_DUMPCAP*/
+/**#define DEBUG_DUMPCAP**/
+/**#define DEBUG_CHILD_DUMPCAP**/
 
 #ifdef DEBUG_CHILD_DUMPCAP
 FILE *debug_log;   /* for logging debug messages to  */
@@ -466,14 +466,20 @@
 /*
  * If we were linked with libcap (not libpcap), make sure we have
  * CAP_NET_ADMIN and CAP_NET_RAW, then relinquish our permissions.
+ * (See comment in main() for details)
  */
 
 static void
 #if 0 /* Set to enable capability debugging */
+/* see 'man cap_to_text()' for explanation of output                         */
+/* '='   means 'all= '  ie: no capabilities                                  */
+/* '=ip' means 'all=ip' ie: all capabilities are permissible and inheritable */
+/* ....                                                                      */
 print_caps(char *pfx) {
     cap_t caps = cap_get_proc();
-    fprintf(stderr, "%s: EUID: %d  Capabilities: %s\n", pfx,
-            geteuid(), cap_to_text(caps, NULL));
+    g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
+          "%s: EUID: %d  Capabilities: %s", pfx,
+          geteuid(), cap_to_text(caps, NULL));
     cap_free(caps);
 #else
 print_caps(char *pfx _U_) {
@@ -483,16 +489,23 @@
 static void
 relinquish_privs_except_capture(void)
 {
-    /* CAP_NET_ADMIN: Promiscuous mode and a truckload of other
+    /* If 'started_with_special_privs' (ie: suid) then enable for 
+     *  ourself the  NET_ADMIN and NET_RAW capabilities and then
+     *  drop our suid privileges.
+     *
+     * CAP_NET_ADMIN: Promiscuous mode and a truckload of other
      *                stuff we don't need (and shouldn't have).
      * CAP_NET_RAW:   Packet capture (raw sockets).
      */
-    cap_value_t cap_list[2] = { CAP_NET_ADMIN, CAP_NET_RAW };
-    cap_t caps = cap_init();
-    int cl_len = sizeof(cap_list) / sizeof(cap_value_t);
 
     if (started_with_special_privs()) {
+        cap_value_t cap_list[2] = { CAP_NET_ADMIN, CAP_NET_RAW };
+        int cl_len = sizeof(cap_list) / sizeof(cap_value_t);
+
+        cap_t caps = cap_init();    /* all capabilities initialized to off */
+
         print_caps("Pre drop, pre set");
+
         if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) {
             cmdarg_err("prctl() fail return: %s", strerror(errno));
         }
@@ -504,21 +517,35 @@
             cmdarg_err("cap_set_proc() fail return: %s", strerror(errno));
         }
         print_caps("Pre drop, post set");
-    }
 
-    relinquish_special_privs_perm();
+        relinquish_special_privs_perm();
 
-    if (started_with_special_privs()) {
         print_caps("Post drop, pre set");
         cap_set_flag(caps, CAP_EFFECTIVE,   cl_len, cap_list, CAP_SET);
         if (cap_set_proc(caps)) {
             cmdarg_err("cap_set_proc() fail return: %s", strerror(errno));
         }
         print_caps("Post drop, post set");
+
+        cap_free(caps);
     }
+}
+
 
+static void
+relinquish_all_capabilities()
+{
+    /* Drop any and all capabilities this process may have.            */
+    /* Allowed whether or not process has any privileges.              */
+    cap_t caps = cap_init();    /* all capabilities initialized to off */
+    print_caps("Pre-clear");
+    if (cap_set_proc(caps)) {
+        cmdarg_err("cap_set_proc() fail return: %s", strerror(errno));
+    }
+    print_caps("Post-clear");
     cap_free(caps);
 }
+
 #endif /* HAVE_LIBCAP */
 
 /* Take care of byte order in the libpcap headers read from pipes.
@@ -1083,8 +1110,15 @@
 		       open_err_str);
 #endif
 
+/* If not using libcap: we now can now set euid/egid to ruid/rgid         */
+/*  to remove any suid privileges.                                        */
+/* If using libcap: we can now remove NET_RAW and NET_ADMIN capabilities  */
+/*  (euid/egid have already previously been set to ruid/rgid.             */
+/* (See comment in main() for details)                                    */
 #ifndef HAVE_LIBCAP
   relinquish_special_privs_perm();
+#else
+  relinquish_all_capabilities();
 #endif
 
   if (ld->pcap_h != NULL) {
@@ -2252,13 +2286,13 @@
   /* (eg: during initialization) will be formatted properly.           */
 
   for (i=1; i<argc; i++) {
-      if (strcmp("-Z", argv[i]) == 0) {
-          capture_child = TRUE;
+    if (strcmp("-Z", argv[i]) == 0) {
+      capture_child = TRUE;
 #ifdef _WIN32
-          /* set output pipe to binary mode, to avoid ugly text conversions */
-	  _setmode(2, O_BINARY);
+      /* set output pipe to binary mode, to avoid ugly text conversions */
+      _setmode(2, O_BINARY);
 #endif
-      }
+    }
   }
 
   /* The default_log_handler will use stdout, which makes trouble in   */
@@ -2316,8 +2350,85 @@
     sigaction(SIGHUP, &action, NULL);
 #endif  /* _WIN32 */
 
+  /* ----------------------------------------------------------------- */
+  /* Privilege and capability handling                                 */
+  /* Cases:                                                            */
+  /* 1. Running not as root or suid root; no special capabilities.     */
+  /*    Action: none                                                   */
+  /*                                                                   */
+  /* 2. Running logged in as root (euid=0; ruid=0); Not using libcap.  */
+  /*    Action: none                                                   */
+  /*                                                                   */
+  /* 3. Running logged in as root (euid=0; ruid=0). Using libcap.      */
+  /*    Action:                                                        */
+  /*      - Near start of program: Enable NET_RAW and NET_ADMIN        */
+  /*        capabilities; Drop all other capabilities;                 */
+  /*      - If not -w  (ie: doing -S or -D, etc) run to completion;    */
+  /*        else: after  pcap_open_live() in capture_loop_open_input() */
+  /*         drop all capabilities (NET_RAW and NET_ADMIN)             */
+  /*         (Note: this means that the process, although logged in    */
+  /*          as root, does not have various permissions such as the   */
+  /*          ability to bypass file access permissions.               */
+  /*      XXX: Should we just leave capabilities alone in this case    */
+  /*          so that user gets expected effect that root can do       */
+  /*          anything ??                                              */
+  /*                                                                   */
+  /* 4. Running as suid root (euid=0, ruid=n); Not using libcap.       */
+  /*    Action:                                                        */
+  /*      - If not -w  (ie: doing -S or -D, etc) run to completion;    */
+  /*        else: after  pcap_open_live() in capture_loop_open_input() */
+  /*         drop same (euid=ruid). (ie: keep suid until after         */
+  /*         pcap_open_live                                            */
+  /*                                                                   */
+  /* 5. Running as suid root (euid=0, ruid=n); Using libcap.           */
+  /*    Action:                                                        */
+  /*      - Near start of program: Enable NET_RAW and NET_ADMIN        */
+  /*        capabilities; Drop all other capabilities;                 */
+  /*        Drop suid privileges (euid=ruid).                          */
+  /*      - If not -w  (ie: doing -S or -D, etc) run to completion;    */
+  /*        else: after  pcap_open_live() in capture_loop_open_input() */
+  /*         drop all capabilities (NET_RAW and NET_ADMIN)             */
+  /*                                                                   */
+  /*      XXX: For some Linux versions/distros with capabilities       */
+  /*        a 'normal' process with any capabilities cannot be         */
+  /*        'killed' (signaled) from another (same uid) non-privileged */
+  /*        process.                                                   */
+  /*        For example: If (non-suid) Wireshark forks a               */
+  /*        child suid dumpcap which acts as described here (case 5),  */
+  /*        Wireshark will be unable to kill (signal) the child        */
+  /*        dumpcap process until the capabilities have been dropped   */
+  /*        (after pcap_open_live()).                                  */
+  /*        This behaviour will apparently be changed in the kernel    */
+  /*        to allow the kill (signal) in this case.                   */
+  /*        See the following for details:                             */
+  /*           http://www.mail-archive.com/  [wrapped]                 */ 
+  /*             linux-security-module@vger.kernel.org/msg02913.html   */
+  /*                                                                   */
+  /*        It is therefore conceivable that if dumpcap somehow hangs  */
+  /*        in pcap_open_live or before that wireshark will not        */
+  /*        be able to stop dumpcap using a signal (USR1, TERM, etc).  */
+  /*        In this case, exiting wireshark will kill the child        */
+  /*        dumpcap process.                                           */
+  /*                                                                   */
+  /* 6. Not root or suid root; Running with NET_RAW & NET_ADMIN        */
+  /*     capabilities; Using libcap.  Note: capset cmd (which see)     */
+  /*     used to assign capabilities to file.                          */
+  /*    Action:                                                        */
+  /*      - If not -w  (ie: doing -S or -D, etc) run to completion;    */
+  /*        else: after  pcap_open_live() in capture_loop_open_input() */
+  /*         drop all capabilities (NET_RAW and NET_ADMIN)             */
+  /*                                                                   */
+  /* ToDo: -S (stats) should drop privileges/capabilities when no      */
+  /*       onger required (similar to capture).                        */
+  /*                                                                   */
+  /* ----------------------------------------------------------------- */
+
   get_credential_info();
+
 #ifdef HAVE_LIBCAP
+  /* If 'started with special privileges' (and using libcap)  */
+  /*   Set to keep only NET_RAW and NET_ADMIN capabilities;   */
+  /*   Set euid/egid = ruid/rgid to remove suid privileges    */
   relinquish_privs_except_capture();
 #endif
 
@@ -2380,34 +2491,33 @@
 #endif /* _WIN32 */
         status = capture_opts_add_opt(capture_opts, opt, optarg, &start_capture);
         if(status != 0) {
-            exit_main(status);
+          exit_main(status);
         }
         break;
       /*** hidden option: Wireshark child mode (using binary output messages) ***/
       case 'Z':
-          capture_child = TRUE;
+        capture_child = TRUE;
 #ifdef _WIN32
-          /* set output pipe to binary mode, to avoid ugly text conversions */
-	  _setmode(2, O_BINARY);
-          /*
-           * optarg = the control ID, aka the PPID, currently used for the
-           * signal pipe name.
-           */
-          if (strcmp(optarg, SIGNAL_PIPE_CTRL_ID_NONE) != 0) {
-              sig_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT,
-                  optarg);
-              sig_pipe_handle = CreateFile(utf_8to16(sig_pipe_name),
-                  GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
-
-              if (sig_pipe_handle == INVALID_HANDLE_VALUE) {
-                  g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO,
-                      "Signal pipe: Unable to open %s.  Dead parent?",
-                      sig_pipe_name);
-                  exit_main(1);
-              }
+        /* set output pipe to binary mode, to avoid ugly text conversions */
+	_setmode(2, O_BINARY);
+        /*
+         * optarg = the control ID, aka the PPID, currently used for the
+         * signal pipe name.
+         */
+        if (strcmp(optarg, SIGNAL_PIPE_CTRL_ID_NONE) != 0) {
+          sig_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, optarg);
+          sig_pipe_handle = CreateFile(utf_8to16(sig_pipe_name),
+              GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
+
+          if (sig_pipe_handle == INVALID_HANDLE_VALUE) {
+            g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO,
+                  "Signal pipe: Unable to open %s.  Dead parent?",
+                  sig_pipe_name);
+            exit_main(1);
           }
+        }
 #endif
-          break;
+        break;
 
       /*** all non capture option specific ***/
       case 'D':        /* Print a list of capture devices and exit */
@@ -2435,8 +2545,8 @@
   argc -= optind;
   argv += optind;
   if (argc >= 1) {
-      /* user specified file name as regular command-line argument */
-      /* XXX - use it as the capture file name (or something else)? */
+    /* user specified file name as regular command-line argument */
+    /* XXX - use it as the capture file name (or something else)? */
     argc--;
     argv++;
   }
@@ -2487,7 +2597,7 @@
   }
 
   if (capture_opts_trim_iface(capture_opts, NULL) == FALSE) {
-	cmdarg_err("No capture interfaces available (maybe lack of privileges?).");
+    /* cmdarg_err() already called .... */
     exit_main(1);
   }
 
@@ -2512,11 +2622,11 @@
   /* Now start the capture. */
 
   if(capture_loop_start(capture_opts, &stats_known, &stats) == TRUE) {
-      /* capture ok */
-      exit_main(0);
+    /* capture ok */
+    exit_main(0);
   } else {
-      /* capture failed */
-      exit_main(1);
+    /* capture failed */
+    exit_main(1);
   }
 }
 
@@ -2582,15 +2692,15 @@
 #if defined(DEBUG_DUMPCAP) || defined(DEBUG_CHILD_DUMPCAP)
   if( !(log_level & G_LOG_LEVEL_MASK & ~(G_LOG_LEVEL_DEBUG|G_LOG_LEVEL_INFO))) {
 #ifdef DEBUG_DUMPCAP
-      fprintf(stderr, "%s", msg);
-      fflush(stderr);
+    fprintf(stderr, "%s", msg);
+    fflush(stderr);
 #endif
 #ifdef DEBUG_CHILD_DUMPCAP
-      fprintf(debug_log, "%s", msg);
-      fflush(debug_log);
+    fprintf(debug_log, "%s", msg);
+    fflush(debug_log);
 #endif
-      g_free(msg);
-      return;
+    g_free(msg);
+    return;
   }
 #endif
 



1.1                  net-analyzer/wireshark/files/wireshark-1.0.0_rc1-fix-setcap-EPERM.patch

file : http://sources.gentoo.org/viewcvs.py/gentoo-x86/net-analyzer/wireshark/files/wireshark-1.0.0_rc1-fix-setcap-EPERM.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewcvs.py/gentoo-x86/net-analyzer/wireshark/files/wireshark-1.0.0_rc1-fix-setcap-EPERM.patch?rev=1.1&content-type=text/plain

Index: wireshark-1.0.0_rc1-fix-setcap-EPERM.patch
===================================================================
Author: 	gerald
Date: 	Thu Mar 20 19:18:33 2008 UTC (2 days, 16 hours ago)
Log Message: 	

Don't call cap_set_proc() unless we were started with elevated privileges.
Otherwise, we might print dumpcap: cap_set_proc() fail return: Operation not
permitted to stderr.

--- trunk/dumpcap.c	2008/03/20 00:30:47	24703
+++ trunk/dumpcap.c	2008/03/20 19:18:33	24704
@@ -508,12 +508,15 @@
 
     relinquish_special_privs_perm();
 
-    print_caps("Post drop, pre set");
-    cap_set_flag(caps, CAP_EFFECTIVE,   cl_len, cap_list, CAP_SET);
-    if (cap_set_proc(caps)) {
-        cmdarg_err("cap_set_proc() fail return: %s", strerror(errno));
+    if (started_with_special_privs()) {
+        print_caps("Post drop, pre set");
+        cap_set_flag(caps, CAP_EFFECTIVE,   cl_len, cap_list, CAP_SET);
+        if (cap_set_proc(caps)) {
+            cmdarg_err("cap_set_proc() fail return: %s", strerror(errno));
+        }
+        print_caps("Post drop, post set");
     }
-    print_caps("Post drop, post set");
+
     cap_free(caps);
 }
 #endif /* HAVE_LIBCAP */



-- 
gentoo-commits@lists.gentoo.org mailing list



             reply	other threads:[~2008-03-23 14:06 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-23 14:06 Peter Volkov (pva) [this message]
  -- strict thread matches above, loose matches on Subject: below --
2008-04-01 19:51 [gentoo-commits] gentoo-x86 commit in net-analyzer/wireshark/files: wireshark-1.0.0_rc1-fix-stop-capture.patch wireshark-1.0.0_rc1-fix-setcap-EPERM.patch Peter Volkov (pva)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E1JdQqD-0003VO-Ec@stork.gentoo.org \
    --to=pva@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox