components/quagga/patches/75-privs-basicprivset.patch
author Mike Sullivan <Mike.Sullivan@Oracle.COM>
Wed, 29 Aug 2012 11:05:56 -0700
changeset 957 255465c5756f
parent 417 7c10b5cba79b
permissions -rw-r--r--
Close of build 04.
diff --git lib/privs.c lib/privs.c
index d290a59..d4dcdf2 100644
--- lib/privs.c
+++ lib/privs.c
@@ -2,7 +2,7 @@
  * Zebra privileges.
  *
  * Copyright (C) 2003 Paul Jakma.
- * Copyright (C) 2005 Sun Microsystems, Inc.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
  *
  * This file is part of GNU Zebra.
  *
@@ -351,6 +351,26 @@ zprivs_caps_terminate (void)
  * - http://blogs.sun.com/roller/page/gbrunett?entry=privilege_enabling_set_id_programs1
  */
 
+static pset_t *
+zprivs_caps_minimal ()
+{
+  pset_t *minimal;
+
+  if ((minimal = priv_str_to_set("basic", ",", NULL)) == NULL)
+    {
+      fprintf (stderr, "%s: couldn't get basic set!\n", __func__);
+      exit (1);
+    }
+
+   /* create a minimal privilege set from the basic set */
+  (void) priv_delset(minimal, PRIV_PROC_EXEC);
+  (void) priv_delset(minimal, PRIV_PROC_INFO);
+  (void) priv_delset(minimal, PRIV_PROC_SESSION);
+  (void) priv_delset(minimal, PRIV_FILE_LINK_ANY);
+
+  return  minimal;
+}
+
 /* convert zebras privileges to system capabilities */
 static pset_t *
 zcaps2sys (zebra_capabilities_t *zcaps, int num)
@@ -379,26 +399,34 @@ zcaps2sys (zebra_capabilities_t *zcaps, int num)
 int 
 zprivs_change_caps (zebra_privs_ops_t op)
 {
+  pset_t *privset;
   
   /* should be no possibility of being called without valid caps */
   assert (zprivs_state.syscaps_p);
   if (!zprivs_state.syscaps_p)
     {
+      fprintf (stderr, "%s: Eek, missing privileged caps!", __func__);
+      exit (1);
+    }
+
+  assert (zprivs_state.caps);
+  if (!zprivs_state.caps)
+    {
       fprintf (stderr, "%s: Eek, missing caps!", __func__);
       exit (1);
     }
-  
-  /* to raise: copy original permitted into our working effective set
-   * to lower: just clear the working effective set
+
+  /* to raise: copy original permitted as our working effective set
+   * to lower: copy regular effective set stored in zprivs_state.caps
    */
   if (op == ZPRIVS_RAISE)
-    priv_copyset (zprivs_state.syscaps_p, zprivs_state.caps);
+    privset = zprivs_state.syscaps_p;
   else if (op == ZPRIVS_LOWER)
-    priv_emptyset (zprivs_state.caps);
+    privset = zprivs_state.caps;
   else
     return -1;
   
-  if (setppriv (PRIV_SET, PRIV_EFFECTIVE, zprivs_state.caps) != 0)
+  if (setppriv (PRIV_SET, PRIV_EFFECTIVE, privset) != 0)
     return -1;
   
   return 0;
@@ -426,15 +454,15 @@ zprivs_state_caps (void)
     }
   else
     {
-      if (priv_isemptyset (effective) == B_TRUE)
+      if (priv_isequalset (effective, zprivs_state.syscaps_p))
+        result = ZPRIVS_RAISED;
+      else if (priv_isequalset (effective, zprivs_state.caps))
         result = ZPRIVS_LOWERED;
       else
-        result = ZPRIVS_RAISED;
+        result = ZPRIVS_UNKNOWN;
     }
   
-  if (effective)
-    priv_freeset (effective);
-  
+  priv_freeset (effective);
   return result;
 }
 
@@ -442,7 +470,7 @@ static void
 zprivs_caps_init (struct zebra_privs_t *zprivs)
 {
   pset_t *basic;
-  pset_t *empty;
+  pset_t *minimal;
   
   /* the specified sets */
   zprivs_state.syscaps_p = zcaps2sys (zprivs->caps_p, zprivs->cap_num_p);
@@ -470,14 +498,6 @@ zprivs_caps_init (struct zebra_privs_t *zprivs)
   priv_union (basic, zprivs_state.syscaps_p);
   priv_freeset (basic);
   
-  /* we need an empty set for 'effective', potentially for inheritable too */
-  if ( (empty = priv_allocset()) == NULL)
-    {
-      fprintf (stderr, "%s: couldn't get empty set!\n", __func__);
-      exit (1);
-    }
-  priv_emptyset (empty);
-  
   /* Hey kernel, we know about privileges! 
    * this isn't strictly required, use of setppriv should have same effect
    */
@@ -520,16 +540,19 @@ zprivs_caps_init (struct zebra_privs_t *zprivs)
       exit (1);
     }
 
-  /* now clear the effective set and we're ready to go */
-  if (setppriv (PRIV_SET, PRIV_EFFECTIVE, empty))
+  /* we need a minimal basic set for 'effective', potentially for inheritable too */
+  minimal = zprivs_caps_minimal();
+
+  /* now set the effective set with a subset of basic privileges */
+  if (setppriv (PRIV_SET, PRIV_EFFECTIVE, minimal))
     {
       fprintf (stderr, "%s: error setting effective set!, %s\n", __func__,
                safe_strerror (errno) );
       exit (1);
     }
   
-  /* we'll use this as our working-storage privset */
-  zprivs_state.caps = empty;
+  /* we'll use the minimal set as our working-storage privset */
+  zprivs_state.caps = minimal;
   
   /* set methods for the caller to use */
   zprivs->change = zprivs_change_caps;
@@ -541,8 +564,7 @@ zprivs_caps_terminate (void)
 {
   assert (zprivs_state.caps);
   
-  /* clear all capabilities */
-  priv_emptyset (zprivs_state.caps);
+  /* clear all capabilities by using working-storage privset */
   setppriv (PRIV_SET, PRIV_EFFECTIVE, zprivs_state.caps);
   setppriv (PRIV_SET, PRIV_PERMITTED, zprivs_state.caps);
   setppriv (PRIV_SET, PRIV_INHERITABLE, zprivs_state.caps);