Commit 983200f9 authored by Havoc Pennington's avatar Havoc Pennington

2003-04-19 Havoc Pennington <hp@pobox.com>

	* bus/driver.c (bus_driver_handle_hello): check limits and
	return an error if they are exceeded.

	* bus/connection.c: maintain separate lists of active and inactive
	connections, and a count of each. Maintain count of completed
	connections per user. Implement code to check connection limits.

	* dbus/dbus-list.c (_dbus_list_unlink): export

	* bus/bus.c (bus_context_check_security_policy): enforce a maximum
	number of bytes in the message queue for a connection
parent d3fb6f35
2003-04-19 Havoc Pennington <hp@pobox.com>
* bus/driver.c (bus_driver_handle_hello): check limits and
return an error if they are exceeded.
* bus/connection.c: maintain separate lists of active and inactive
connections, and a count of each. Maintain count of completed
connections per user. Implement code to check connection limits.
* dbus/dbus-list.c (_dbus_list_unlink): export
* bus/bus.c (bus_context_check_security_policy): enforce a maximum
number of bytes in the message queue for a connection
2003-04-18 Havoc Pennington <hp@pobox.com>
* dbus/dbus-auth.c (record_mechanisms): memleak fixes
......
......@@ -45,8 +45,11 @@ struct BusContext
BusRegistry *registry;
BusPolicy *policy;
DBusUserDatabase *user_database;
int activation_timeout; /**< How long to wait for an activation to time out */
int auth_timeout; /**< How long to wait for an authentication to time out */
long max_incoming_bytes; /**< How many incoming messages for a connection */
long max_outgoing_bytes; /**< How many outgoing bytes can be queued for a connection */
long max_message_size; /**< Max size of a single message in bytes */
int activation_timeout; /**< How long to wait for an activation to time out */
int auth_timeout; /**< How long to wait for an authentication to time out */
int max_completed_connections; /**< Max number of authorized connections */
int max_incomplete_connections; /**< Max number of incomplete connections */
int max_connections_per_user; /**< Max number of connections auth'd as same user */
......@@ -210,6 +213,12 @@ new_connection_callback (DBusServer *server,
*/
dbus_connection_disconnect (new_connection);
}
dbus_connection_set_max_received_size (new_connection,
context->max_incoming_bytes);
dbus_connection_set_max_message_size (new_connection,
context->max_message_size);
/* on OOM, we won't have ref'd the connection so it will die. */
}
......@@ -353,6 +362,11 @@ bus_context_new (const DBusString *config_file,
*/
if (!server_data_slot_ref ())
_dbus_assert_not_reached ("second ref of server data slot failed");
/* Make up some numbers! woot! */
context->max_incoming_bytes = _DBUS_ONE_MEGABYTE * 63;
context->max_outgoing_bytes = _DBUS_ONE_MEGABYTE * 63;
context->max_message_size = _DBUS_ONE_MEGABYTE * 32;
#ifdef DBUS_BUILD_TESTS
context->activation_timeout = 6000; /* 6 seconds */
......@@ -375,7 +389,7 @@ bus_context_new (const DBusString *config_file,
* DOS all the other users.
*/
context->max_completed_connections = 1024;
context->user_database = _dbus_user_database_new ();
if (context->user_database == NULL)
{
......@@ -818,6 +832,30 @@ bus_context_get_activation_timeout (BusContext *context)
return context->activation_timeout;
}
int
bus_context_get_auth_timeout (BusContext *context)
{
return context->auth_timeout;
}
int
bus_context_get_max_completed_connections (BusContext *context)
{
return context->max_completed_connections;
}
int
bus_context_get_max_incomplete_connections (BusContext *context)
{
return context->max_incomplete_connections;
}
int
bus_context_get_max_connections_per_user (BusContext *context)
{
return context->max_connections_per_user;
}
dbus_bool_t
bus_context_check_security_policy (BusContext *context,
DBusConnection *sender,
......@@ -878,5 +916,17 @@ bus_context_check_security_policy (BusContext *context,
return FALSE;
}
/* See if limits on size have been exceeded */
if (recipient &&
dbus_connection_get_outgoing_size (recipient) >
context->max_outgoing_bytes)
{
const char *dest = dbus_message_get_service (message);
dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
"The destination service \"%s\" has a full message queue",
dest ? dest : DBUS_SERVICE_DBUS);
return FALSE;
}
return TRUE;
}
......@@ -41,29 +41,34 @@ typedef struct BusRegistry BusRegistry;
typedef struct BusService BusService;
typedef struct BusTransaction BusTransaction;
BusContext* bus_context_new (const DBusString *config_file,
int print_addr_fd,
DBusError *error);
void bus_context_shutdown (BusContext *context);
void bus_context_ref (BusContext *context);
void bus_context_unref (BusContext *context);
const char* bus_context_get_type (BusContext *context);
const char* bus_context_get_address (BusContext *context);
BusRegistry* bus_context_get_registry (BusContext *context);
BusConnections* bus_context_get_connections (BusContext *context);
BusActivation* bus_context_get_activation (BusContext *context);
DBusLoop* bus_context_get_loop (BusContext *context);
DBusUserDatabase* bus_context_get_user_database (BusContext *context);
dbus_bool_t bus_context_allow_user (BusContext *context,
unsigned long uid);
BusClientPolicy* bus_context_create_client_policy (BusContext *context,
DBusConnection *connection);
int bus_context_get_activation_timeout (BusContext *context);
dbus_bool_t bus_context_check_security_policy (BusContext *context,
DBusConnection *sender,
DBusConnection *recipient,
DBusMessage *message,
DBusError *error);
BusContext* bus_context_new (const DBusString *config_file,
int print_addr_fd,
DBusError *error);
void bus_context_shutdown (BusContext *context);
void bus_context_ref (BusContext *context);
void bus_context_unref (BusContext *context);
const char* bus_context_get_type (BusContext *context);
const char* bus_context_get_address (BusContext *context);
BusRegistry* bus_context_get_registry (BusContext *context);
BusConnections* bus_context_get_connections (BusContext *context);
BusActivation* bus_context_get_activation (BusContext *context);
DBusLoop* bus_context_get_loop (BusContext *context);
DBusUserDatabase* bus_context_get_user_database (BusContext *context);
dbus_bool_t bus_context_allow_user (BusContext *context,
unsigned long uid);
BusClientPolicy* bus_context_create_client_policy (BusContext *context,
DBusConnection *connection);
int bus_context_get_activation_timeout (BusContext *context);
int bus_context_get_auth_timeout (BusContext *context);
int bus_context_get_max_completed_connections (BusContext *context);
int bus_context_get_max_incomplete_connections (BusContext *context);
int bus_context_get_max_connections_per_user (BusContext *context);
dbus_bool_t bus_context_check_security_policy (BusContext *context,
DBusConnection *sender,
DBusConnection *recipient,
DBusMessage *message,
DBusError *error);
#endif /* BUS_BUS_H */
This diff is collapsed.
......@@ -40,12 +40,18 @@ dbus_bool_t bus_connections_setup_connection (BusConnections *
void bus_connections_foreach (BusConnections *connections,
BusConnectionForeachFunction function,
void *data);
void bus_connections_foreach_active (BusConnections *connections,
BusConnectionForeachFunction function,
void *data);
BusContext* bus_connections_get_context (BusConnections *connections);
BusContext* bus_connection_get_context (DBusConnection *connection);
BusContext* bus_connection_get_context (DBusConnection *connection);
BusConnections* bus_connection_get_connections (DBusConnection *connection);
BusRegistry* bus_connection_get_registry (DBusConnection *connection);
BusActivation* bus_connection_get_activation (DBusConnection *connection);
dbus_bool_t bus_connections_check_limits (BusConnections *connections,
DBusConnection *requesting_completion,
DBusError *error);
dbus_bool_t bus_connection_is_active (DBusConnection *connection);
......
......@@ -48,9 +48,6 @@ static dbus_bool_t
send_one_message (DBusConnection *connection, void *data)
{
SendMessageData *d = data;
if (!bus_connection_is_active (connection))
return TRUE;
if (!bus_context_check_security_policy (d->context,
d->sender,
......@@ -93,7 +90,7 @@ bus_dispatch_broadcast_message (BusTransaction *transaction,
d.transaction = transaction;
d.error = &tmp_error;
bus_connections_foreach (connections, send_one_message, &d);
bus_connections_foreach_active (connections, send_one_message, &d);
if (dbus_error_is_set (&tmp_error))
{
......
......@@ -262,8 +262,23 @@ bus_driver_handle_hello (DBusConnection *connection,
BusService *service;
dbus_bool_t retval;
BusRegistry *registry;
BusConnections *connections;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
/* Note that when these limits are exceeded we don't disconnect the
* connection; we just sort of leave it hanging there until it times
* out or disconnects itself or is dropped due to the max number of
* incomplete connections. It's even OK if the connection wants to
* retry the hello message, we support that.
*/
connections = bus_connection_get_connections (connection);
if (!bus_connections_check_limits (connections, connection,
error))
{
_DBUS_ASSERT_ERROR_IS_SET (error);
return FALSE;
}
if (!_dbus_string_init (&unique_name))
{
......
......@@ -183,11 +183,11 @@ void* dbus_connection_get_data (DBusConnection *connection,
void dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe);
void dbus_connection_set_max_message_size (DBusConnection *connection,
long size);
long dbus_connection_get_max_message_size (DBusConnection *connection);
void dbus_connection_set_max_message_size (DBusConnection *connection,
long size);
long dbus_connection_get_max_message_size (DBusConnection *connection);
void dbus_connection_set_max_received_size (DBusConnection *connection,
long size);
long size);
long dbus_connection_get_max_received_size (DBusConnection *connection);
long dbus_connection_get_outgoing_size (DBusConnection *connection);
......
......@@ -470,7 +470,15 @@ _dbus_list_remove_last (DBusList **list,
return FALSE;
}
static void
/**
* Removes the given link from the list, but doesn't
* free it. _dbus_list_remove_link() both removes the
* link and also frees it.
*
* @param list the list
* @param link the link in the list
*/
void
_dbus_list_unlink (DBusList **list,
DBusList *link)
{
......@@ -487,6 +495,9 @@ _dbus_list_unlink (DBusList **list,
if (*list == link)
*list = link->next;
}
link->next = NULL;
link->prev = NULL;
}
/**
......
......@@ -74,6 +74,8 @@ dbus_bool_t _dbus_list_copy (DBusList **list,
int _dbus_list_get_length (DBusList **list);
DBusList* _dbus_list_alloc_link (void *data);
void _dbus_list_free_link (DBusList *link);
void _dbus_list_unlink (DBusList **list,
DBusList *link);
void _dbus_list_append_link (DBusList **list,
DBusList *link);
void _dbus_list_prepend_link (DBusList **list,
......
......@@ -470,8 +470,8 @@ _dbus_listen_unix_socket (const char *path,
* But there doesn't seem to be a good way to do this.
*
* Just to be extra careful, I threw in the stat() - clearly
* the stat() can't *fix* any security issue, but it probably
* makes it harder to exploit.
* the stat() can't *fix* any security issue, but it at least
* avoids inadvertent/accidental data loss.
*/
{
struct stat sb;
......
......@@ -21,10 +21,6 @@
- Activation needs some careful additional thinking-through.
- Recursive/composite/etc. types and associated API, see mailing list.
- Configuration file (working on that now)
- Property list feature on message bus (list of properties associated
with a connection). May also include message matching rules
that involve the properties of the source or destination
......@@ -46,9 +42,6 @@
- We might consider returning a "no such operation" error in dbus-connection.c
for unhandled messages.
- Abstract the user database, so you can use something other than the system password
database.
- The convenience functions in dbus-bus.h should perhaps have
the signatures that they would have if they were autogenerated
stubs. e.g. the acquire service function. We should also evaluate
......@@ -60,9 +53,6 @@
some basic spec'ing out of the GLib/Qt level stubs/skels stuff will be
needed to understand the right approach.
- sync up DBusWatch and DBusTimeout so that handle_watch() is a method on DBusWatch
similar to the way timeouts work
- there are various bits of code to manage ref/unref of data slots, that should
be merged into a generic facility
......@@ -85,7 +75,5 @@
- We have a limit on the number of messages a connection can send, but
not on how many can be buffered for a given connection.
- make client serial and reply serial unsigned and add dbus_message_get_is_reply()
- other apps can send you a fake DBUS_MESSAGE_LOCAL_DISCONNECT; need to
check for that and disallow it.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment