2003-04-12 Havoc Pennington <hp@pobox.com>
authorHavoc Pennington <hp@redhat.com>
Sun, 13 Apr 2003 00:10:53 +0000 (00:10 +0000)
committerHavoc Pennington <hp@redhat.com>
Sun, 13 Apr 2003 00:10:53 +0000 (00:10 +0000)
* bus/config-parser.c (bus_config_parser_new): fix a memleak

* dbus/dbus-sysdeps.c: change DBusCredentials to use longs for
the pid/gid/uid, just for paranoia.

* test/break-loader.c (randomly_do_n_things): find a byte
containing a type code, and randomly change it to a different
type code.

ChangeLog
bus/config-parser.c
dbus/dbus-auth.c
dbus/dbus-internals.h
dbus/dbus-sysdeps.c
dbus/dbus-sysdeps.h
dbus/dbus-transport.c
test/break-loader.c

index 7808483..60cff00 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2003-04-12  Havoc Pennington  <hp@pobox.com>
 
+       * bus/config-parser.c (bus_config_parser_new): fix a memleak
+
+       * dbus/dbus-sysdeps.c: change DBusCredentials to use longs for
+       the pid/gid/uid, just for paranoia.
+
+       * test/break-loader.c (randomly_do_n_things): find a byte
+       containing a type code, and randomly change it to a different 
+       type code.
+
+2003-04-12  Havoc Pennington  <hp@pobox.com>
+
        * bus/policy.h: change BusPolicy to be the thing from the config
        file, and rename old BusPolicy to BusClientPolicy
 
index 780d175..da5b23f 100644 (file)
@@ -268,6 +268,9 @@ bus_config_parser_new (const DBusString *basedir)
   if (((parser->policy = bus_policy_new ()) == NULL) ||
       !_dbus_string_copy (basedir, 0, &parser->basedir, 0))
     {
+      if (parser->policy)
+        bus_policy_unref (parser->policy);
+      
       _dbus_string_free (&parser->basedir);
       dbus_free (parser);
       return NULL;
index e687dd6..5ee31e5 100644 (file)
@@ -276,17 +276,9 @@ _dbus_auth_new (int size)
   
   auth->refcount = 1;
 
-  auth->credentials.pid = -1;
-  auth->credentials.uid = -1;
-  auth->credentials.gid = -1;
-
-  auth->authorized_identity.pid = -1;
-  auth->authorized_identity.uid = -1;
-  auth->authorized_identity.gid = -1;
-
-  auth->desired_identity.pid = -1;
-  auth->desired_identity.uid = -1;
-  auth->desired_identity.gid = -1;
+  _dbus_credentials_clear (&auth->credentials);
+  _dbus_credentials_clear (&auth->authorized_identity);
+  _dbus_credentials_clear (&auth->desired_identity);
   
   auth->keyring = NULL;
   auth->cookie_id = -1;
@@ -343,14 +335,9 @@ shutdown_mech (DBusAuth *auth)
   auth->authenticated = FALSE;
   auth->already_asked_for_initial_response = FALSE;
   _dbus_string_set_length (&auth->identity, 0);
-  
-  auth->authorized_identity.pid = -1;
-  auth->authorized_identity.uid = -1;
-  auth->authorized_identity.gid = -1;
 
-  auth->desired_identity.pid = -1;
-  auth->desired_identity.uid = -1;
-  auth->desired_identity.gid = -1;
+  _dbus_credentials_clear (&auth->authorized_identity);
+  _dbus_credentials_clear (&auth->desired_identity);
   
   if (auth->mech != NULL)
     {
@@ -680,7 +667,7 @@ sha1_handle_second_client_response (DBusAuth         *auth,
                             "OK\r\n"))
     goto out_3;
 
-  _dbus_verbose ("authenticated client with UID %d using DBUS_COOKIE_SHA1\n",
+  _dbus_verbose ("authenticated client with UID "DBUS_UID_FORMAT" using DBUS_COOKIE_SHA1\n",
                  auth->desired_identity.uid);
   
   auth->authorized_identity = auth->desired_identity;
@@ -963,7 +950,7 @@ static dbus_bool_t
 handle_server_data_external_mech (DBusAuth         *auth,
                                   const DBusString *data)
 {
-  if (auth->credentials.uid < 0)
+  if (auth->credentials.uid == DBUS_UID_UNSET)
     {
       _dbus_verbose ("no credentials, mechanism EXTERNAL can't authenticate\n");
       return send_rejected (auth);
@@ -1000,9 +987,7 @@ handle_server_data_external_mech (DBusAuth         *auth,
         return FALSE;
     }
 
-  auth->desired_identity.pid = -1;
-  auth->desired_identity.uid = -1;
-  auth->desired_identity.gid = -1;
+  _dbus_credentials_clear (&auth->desired_identity);
   
   /* If auth->identity is still empty here, then client
    * responded with an empty string after we poked it for
@@ -1023,9 +1008,10 @@ handle_server_data_external_mech (DBusAuth         *auth,
         }
     }
 
-  if (auth->desired_identity.uid < 0)
+  if (auth->desired_identity.uid == DBUS_UID_UNSET)
     {
-      _dbus_verbose ("desired UID %d is no good\n", auth->desired_identity.uid);
+      _dbus_verbose ("desired user %s is no good\n",
+                     _dbus_string_get_const_data (&auth->identity));
       return send_rejected (auth);
     }
   
@@ -1037,7 +1023,8 @@ handle_server_data_external_mech (DBusAuth         *auth,
                                 "OK\r\n"))
         return FALSE;
 
-      _dbus_verbose ("authenticated client with UID %d matching socket credentials UID %d\n",
+      _dbus_verbose ("authenticated client with UID "DBUS_UID_FORMAT
+                     " matching socket credentials UID "DBUS_UID_FORMAT"\n",
                      auth->desired_identity.uid,
                      auth->credentials.uid);
       
@@ -1049,7 +1036,10 @@ handle_server_data_external_mech (DBusAuth         *auth,
     }
   else
     {
-      _dbus_verbose ("credentials uid=%d gid=%d do not allow uid=%d gid=%d\n",
+      _dbus_verbose ("credentials uid="DBUS_UID_FORMAT
+                     " gid="DBUS_GID_FORMAT
+                     " do not allow uid="DBUS_UID_FORMAT
+                     " gid="DBUS_GID_FORMAT"\n",
                      auth->credentials.uid, auth->credentials.gid,
                      auth->desired_identity.uid, auth->desired_identity.gid);
       return send_rejected (auth);
@@ -2266,15 +2256,9 @@ _dbus_auth_get_identity (DBusAuth               *auth,
                          DBusCredentials        *credentials)
 {
   if (auth->authenticated)
-    {
-      *credentials = auth->authorized_identity;
-    }
+    *credentials = auth->authorized_identity;
   else
-    {
-      credentials->pid = -1;
-      credentials->uid = -1;
-      credentials->gid = -1;
-    }
+    _dbus_credentials_clear (credentials);
 }
 
 /**
index 04859ef..3ffecbd 100644 (file)
 
 DBUS_BEGIN_DECLS;
 
-#if     __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
-#define _DBUS_GNUC_PRINTF( format_idx, arg_idx )    \
-  __attribute__((__format__ (__printf__, format_idx, arg_idx)))
-#define _DBUS_GNUC_SCANF( format_idx, arg_idx )     \
-  __attribute__((__format__ (__scanf__, format_idx, arg_idx)))
-#define _DBUS_GNUC_FORMAT( arg_idx )                \
-  __attribute__((__format_arg__ (arg_idx)))
-#define _DBUS_GNUC_NORETURN                         \
-  __attribute__((__noreturn__))
-#else   /* !__GNUC__ */
-#define _DBUS_GNUC_PRINTF( format_idx, arg_idx )
-#define _DBUS_GNUC_SCANF( format_idx, arg_idx )
-#define _DBUS_GNUC_FORMAT( arg_idx )
-#define _DBUS_GNUC_NORETURN
-#endif  /* !__GNUC__ */
-
 void _dbus_warn               (const char *format,
                                ...) _DBUS_GNUC_PRINTF (1, 2);
 void _dbus_verbose_real       (const char *format,
index bb47187..b941c19 100644 (file)
@@ -755,10 +755,8 @@ _dbus_read_credentials_unix_socket  (int              client_fd,
   _dbus_assert (sizeof (pid_t) <= sizeof (credentials->pid));
   _dbus_assert (sizeof (uid_t) <= sizeof (credentials->uid));
   _dbus_assert (sizeof (gid_t) <= sizeof (credentials->gid));
-  
-  credentials->pid = -1;
-  credentials->uid = -1;
-  credentials->gid = -1;
+
+  _dbus_credentials_clear (credentials);
 
 #if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED)
   /* Set the socket to receive credentials on the next message */
@@ -845,7 +843,10 @@ _dbus_read_credentials_unix_socket  (int              client_fd,
 #endif
   }
 
-  _dbus_verbose ("Credentials: pid %d  uid %d  gid %d\n",
+  _dbus_verbose ("Credentials:"
+                 "  pid "DBUS_PID_FORMAT
+                 "  uid "DBUS_UID_FORMAT
+                 "  gid "DBUS_GID_FORMAT"\n",
                 credentials->pid,
                 credentials->uid,
                 credentials->gid);
@@ -1367,7 +1368,7 @@ store_user_info (struct passwd    *p,
  */
 static dbus_bool_t
 get_user_info (const DBusString *username,
-               int               uid,
+               dbus_uid_t        uid,
                DBusCredentials  *credentials,
                DBusString       *homedir,
                DBusString       *username_out)
@@ -1376,14 +1377,10 @@ get_user_info (const DBusString *username,
       
   /* exactly one of username/uid provided */
   _dbus_assert (username != NULL || uid >= 0);
-  _dbus_assert (username == NULL || uid < 0);
+  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
 
   if (credentials)
-    {
-      credentials->pid = -1;
-      credentials->uid = -1;
-      credentials->gid = -1;
-    }
+    _dbus_credentials_clear (credentials);
   
   if (username != NULL)
     username_c_str = _dbus_string_get_const_data (username);
@@ -1453,6 +1450,20 @@ get_user_info (const DBusString *username,
 }
 
 /**
+ * Sets fields in DBusCredentials to DBUS_PID_UNSET,
+ * DBUS_UID_UNSET, DBUS_GID_UNSET.
+ *
+ * @param credentials the credentials object to fill in
+ */
+void
+_dbus_credentials_clear (DBusCredentials *credentials)
+{
+  credentials->pid = DBUS_PID_UNSET;
+  credentials->uid = DBUS_UID_UNSET;
+  credentials->gid = DBUS_GID_UNSET;
+}
+
+/**
  * Gets the credentials corresponding to the given username.
  *
  * @param username the username
@@ -1531,10 +1542,8 @@ _dbus_user_info_from_current_process (const DBusString      **username,
           _DBUS_UNLOCK (user_info);
           return FALSE;
         }
-      
-      u.creds.uid = -1;
-      u.creds.gid = -1;
-      u.creds.pid = -1;
+
+      _dbus_credentials_clear (&u.creds);
 
       if (!get_user_info (NULL, getuid (),
                           &u.creds, &u.dir, &u.name))
@@ -1596,9 +1605,7 @@ _dbus_credentials_from_uid_string (const DBusString      *uid_str,
   int end;
   long uid;
 
-  credentials->pid = -1;
-  credentials->uid = -1;
-  credentials->gid = -1;
+  _dbus_credentials_clear (credentials);
   
   if (_dbus_string_get_length (uid_str) == 0)
     {
@@ -1659,9 +1666,9 @@ dbus_bool_t
 _dbus_credentials_match (const DBusCredentials *expected_credentials,
                          const DBusCredentials *provided_credentials)
 {
-  if (provided_credentials->uid < 0)
+  if (provided_credentials->uid == DBUS_UID_UNSET)
     return FALSE;
-  else if (expected_credentials->uid < 0)
+  else if (expected_credentials->uid == DBUS_UID_UNSET)
     return FALSE;
   else if (provided_credentials->uid == 0)
     return TRUE;
@@ -1773,7 +1780,7 @@ _dbus_get_groups (unsigned long   uid,
 
   if (!get_user_info (NULL, uid, &creds,
                       NULL, &username) ||
-      creds.gid < 0)
+      creds.gid == DBUS_GID_UNSET)
     goto out;
 
   username_c = _dbus_string_get_const_data (&username);
@@ -1848,7 +1855,7 @@ _dbus_get_groups (unsigned long   uid,
 dbus_bool_t
 _dbus_string_append_our_uid (DBusString *str)
 {
-  return _dbus_string_append_int (str, getuid ());
+  return _dbus_string_append_uint (str, getuid ());
 }
 
 /**
@@ -3226,8 +3233,8 @@ _dbus_write_pid_file (const DBusString *filename,
  * @returns #FALSE on failure
  */
 dbus_bool_t
-_dbus_change_identity  (unsigned long  uid,
-                        unsigned long  gid,
+_dbus_change_identity  (dbus_uid_t     uid,
+                        dbus_gid_t     gid,
                         DBusError     *error)
 {
   /* Set GID first, or the setuid may remove our permission
index 0a4a34d..74e0cb6 100644 (file)
@@ -47,7 +47,23 @@ DBUS_BEGIN_DECLS;
  * dbus-memory.c)
  */
 
-void _dbus_abort (void);
+#if     __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
+#define _DBUS_GNUC_PRINTF( format_idx, arg_idx )    \
+  __attribute__((__format__ (__printf__, format_idx, arg_idx)))
+#define _DBUS_GNUC_SCANF( format_idx, arg_idx )     \
+  __attribute__((__format__ (__scanf__, format_idx, arg_idx)))
+#define _DBUS_GNUC_FORMAT( arg_idx )                \
+  __attribute__((__format_arg__ (arg_idx)))
+#define _DBUS_GNUC_NORETURN                         \
+  __attribute__((__noreturn__))
+#else   /* !__GNUC__ */
+#define _DBUS_GNUC_PRINTF( format_idx, arg_idx )
+#define _DBUS_GNUC_SCANF( format_idx, arg_idx )
+#define _DBUS_GNUC_FORMAT( arg_idx )
+#define _DBUS_GNUC_NORETURN
+#endif  /* !__GNUC__ */
+
+void _dbus_abort (void) _DBUS_GNUC_NORETURN;
 
 const char* _dbus_getenv (const char *varname);
 dbus_bool_t _dbus_setenv (const char *varname,
@@ -68,12 +84,24 @@ int _dbus_write_two (int               fd,
                      int               start2,
                      int               len2);
 
+typedef unsigned long dbus_pid_t;
+typedef unsigned long dbus_uid_t;
+typedef unsigned long dbus_gid_t;
+
+#define DBUS_PID_UNSET ((dbus_pid_t) -1)
+#define DBUS_UID_UNSET ((dbus_uid_t) -1)
+#define DBUS_GID_UNSET ((dbus_gid_t) -1)
+
+#define DBUS_PID_FORMAT "%lu"
+#define DBUS_UID_FORMAT "%lu"
+#define DBUS_GID_FORMAT "%lu"
+
 typedef struct
 {
-  /* -1 if not available */
-  int pid;
-  int uid;
-  int gid;
+  /* Set to DBUS_PID_UNSET etc. if not available */
+  dbus_pid_t pid;
+  dbus_uid_t uid;
+  dbus_gid_t gid;
 } DBusCredentials;
 
 int _dbus_connect_unix_socket (const char     *path,
@@ -95,9 +123,10 @@ dbus_bool_t _dbus_send_credentials_unix_socket (int              server_fd,
                                                 DBusError       *error);
 
 
+void        _dbus_credentials_clear                (DBusCredentials       *credentials);
 dbus_bool_t _dbus_credentials_from_username        (const DBusString      *username,
                                                     DBusCredentials       *credentials);
-dbus_bool_t _dbus_credentials_from_user_id         (unsigned long          user_id,
+dbus_bool_t _dbus_credentials_from_user_id         (dbus_uid_t             user_id,
                                                     DBusCredentials       *credentials);
 dbus_bool_t _dbus_credentials_from_uid_string      (const DBusString      *uid_str,
                                                     DBusCredentials       *credentials);
@@ -114,9 +143,9 @@ dbus_bool_t _dbus_user_info_from_current_process (const DBusString      **userna
                                                   const DBusCredentials **credentials);
 
 dbus_bool_t _dbus_get_group_id (const DBusString  *group_name,
-                                unsigned long     *gid);
-dbus_bool_t _dbus_get_groups   (unsigned long      uid,
-                                unsigned long    **group_ids,
+                                dbus_gid_t        *gid);
+dbus_bool_t _dbus_get_groups   (dbus_uid_t         uid,
+                                dbus_gid_t       **group_ids,
                                 int               *n_group_ids);
 
 unsigned long _dbus_getpid (void);
@@ -192,14 +221,14 @@ void _dbus_disable_sigpipe (void);
 
 void _dbus_fd_set_close_on_exec (int fd);
 
-void _dbus_exit (int code);
+void _dbus_exit (int code) _DBUS_GNUC_NORETURN;
 
 typedef struct
 {
   unsigned long mode;
   unsigned long nlink;
-  unsigned long uid;
-  unsigned long gid;
+  dbus_uid_t    uid;
+  dbus_gid_t    gid;
   unsigned long size;
   unsigned long atime;
   unsigned long mtime;
index e715bd1..f9b3d8a 100644 (file)
@@ -483,14 +483,15 @@ _dbus_transport_get_is_authenticated (DBusTransport *transport)
                                                       auth_identity.uid,
                                                       transport->unix_user_data))
                 {
-                  _dbus_verbose ("Client UID %d was rejected, disconnecting\n",
+                  _dbus_verbose ("Client UID "DBUS_UID_FORMAT
+                                 " was rejected, disconnecting\n",
                                  auth_identity.uid);
                   _dbus_transport_disconnect (transport);
                   return FALSE;
                 }
               else
                 {
-                  _dbus_verbose ("Client UID %d authorized\n", auth_identity.uid);
+                  _dbus_verbose ("Client UID "DBUS_UID_FORMAT" authorized\n", auth_identity.uid);
                 }
             }
           else
@@ -502,14 +503,16 @@ _dbus_transport_get_is_authenticated (DBusTransport *transport)
               if (!_dbus_credentials_match (&our_identity,
                                             &auth_identity))
                 {
-                  _dbus_verbose ("Client authorized as UID %d but our UID is %d, disconnecting\n",
+                  _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
+                                 " but our UID is "DBUS_UID_FORMAT", disconnecting\n",
                                  auth_identity.uid, our_identity.uid);
                   _dbus_transport_disconnect (transport);
                   return FALSE;
                 }
               else
                 {
-                  _dbus_verbose ("Client authorized as UID %d matching our UID %d\n",
+                  _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
+                                 " matching our UID "DBUS_UID_FORMAT"\n",
                                  auth_identity.uid, our_identity.uid);
                 }
             }
index e2ce681..1ddaec4 100644 (file)
@@ -347,10 +347,12 @@ randomly_set_extreme_ints (const DBusString *orig_data,
     _DBUS_UINT_MAX - 1,
     _DBUS_INT_MAX - 2,
     _DBUS_UINT_MAX - 2,
-    (unsigned int) (_DBUS_INT_MAX + 1),
-    (unsigned int) (_DBUS_UINT_MAX + 1),
-    _DBUS_INT_MAX + 2,
-    _DBUS_UINT_MAX + 2,
+    _DBUS_INT_MAX - 17,
+    _DBUS_UINT_MAX - 17,
+    _DBUS_INT_MAX / 2,
+    _DBUS_INT_MAX / 3,
+    _DBUS_UINT_MAX / 2,
+    _DBUS_UINT_MAX / 3,
     0, 1, 2, 3,
     (unsigned int) -1,
     (unsigned int) -2,
@@ -390,6 +392,45 @@ randomly_set_extreme_ints (const DBusString *orig_data,
                             extreme_ints[which]);
 }
 
+static void
+randomly_change_one_type (const DBusString *orig_data,
+                          DBusString       *mutated)
+{
+  int i;
+  int len;
+  
+  if (orig_data != mutated)
+    {
+      _dbus_string_set_length (mutated, 0);
+      
+      if (!_dbus_string_copy (orig_data, 0, mutated, 0))
+        _dbus_assert_not_reached ("out of mem");
+    }
+
+  if (_dbus_string_get_length (mutated) == 0)
+    return;
+
+  len = _dbus_string_get_length (mutated);
+  i = random_int_in_range (0, len);
+
+  /* Look for a type starting at a random location,
+   * and replace with a different type
+   */
+  while (i < len)
+    {
+      int b;
+      b = _dbus_string_get_byte (mutated, i);
+      if (b > DBUS_TYPE_INVALID && b <= DBUS_TYPE_LAST)
+        {
+          _dbus_string_set_byte (mutated, i,
+                                 random_int_in_range (DBUS_TYPE_INVALID,
+                                                      DBUS_TYPE_LAST + 1));
+          return;
+        }
+      ++i;
+    }
+}
+
 static int times_we_did_each_thing[6] = { 0, };
 
 static void
@@ -406,7 +447,8 @@ randomly_do_n_things (const DBusString *orig_data,
       randomly_add_one_byte,
       randomly_remove_one_byte,
       randomly_modify_length,
-      randomly_set_extreme_ints
+      randomly_set_extreme_ints,
+      randomly_change_one_type
     };
 
   _dbus_string_set_length (mutated, 0);
@@ -501,6 +543,15 @@ find_breaks_based_on (const DBusString   *filename,
 
       ++i;
     }
+
+  i = 0;
+  while (i < 50)
+    {
+      randomly_change_one_type (&orig_data, &mutated);
+      try_mutated_data (&mutated);
+
+      ++i;
+    }
   
   i = 0;
   while (i < 15)