diff options
31 files changed, 302 insertions, 84 deletions
@@ -56,6 +56,7 @@ struct BusContext unsigned int fork : 1; unsigned int syslog : 1; unsigned int keep_umask : 1; + unsigned int allow_anonymous : 1; }; static dbus_int32_t server_data_slot = -1; @@ -190,6 +191,9 @@ new_connection_callback (DBusServer *server, dbus_connection_set_max_message_size (new_connection, context->limits.max_message_size); + dbus_connection_set_allow_anonymous (new_connection, + context->allow_anonymous); + /* on OOM, we won't have ref'd the connection so it will die. */ } @@ -388,6 +392,7 @@ process_config_first_time_only (BusContext *context, context->fork = bus_config_parser_get_fork (parser); context->syslog = bus_config_parser_get_syslog (parser); context->keep_umask = bus_config_parser_get_keep_umask (parser); + context->allow_anonymous = bus_config_parser_get_allow_anonymous (parser); _DBUS_ASSERT_ERROR_IS_CLEAR (error); retval = TRUE; diff --git a/bus/config-parser-common.c b/bus/config-parser-common.c index 88e099ac..5cdbba26 100644 --- a/bus/config-parser-common.c +++ b/bus/config-parser-common.c @@ -122,6 +122,10 @@ bus_config_parser_element_name_to_type (const char *name) { return ELEMENT_KEEP_UMASK; } + else if (strcmp (name, "allow_anonymous") == 0) + { + return ELEMENT_ALLOW_ANONYMOUS; + } return ELEMENT_NONE; } @@ -174,6 +178,8 @@ bus_config_parser_element_type_to_name (ElementType type) return "syslog"; case ELEMENT_KEEP_UMASK: return "keep_umask"; + case ELEMENT_ALLOW_ANONYMOUS: + return "allow_anonymous"; } _dbus_assert_not_reached ("bad element type"); diff --git a/bus/config-parser-common.h b/bus/config-parser-common.h index ae40d089..2c296433 100644 --- a/bus/config-parser-common.h +++ b/bus/config-parser-common.h @@ -48,8 +48,9 @@ typedef enum ELEMENT_ASSOCIATE, ELEMENT_STANDARD_SESSION_SERVICEDIRS, ELEMENT_STANDARD_SYSTEM_SERVICEDIRS, + ELEMENT_KEEP_UMASK, ELEMENT_SYSLOG, - ELEMENT_KEEP_UMASK + ELEMENT_ALLOW_ANONYMOUS } ElementType; ElementType bus_config_parser_element_name_to_type (const char *element_name); diff --git a/bus/config-parser.c b/bus/config-parser.c index 38ce8a1d..c3e8fba1 100644 --- a/bus/config-parser.c +++ b/bus/config-parser.c @@ -115,6 +115,8 @@ struct BusConfigParser unsigned int keep_umask : 1; /**< TRUE to keep original umask when forking */ unsigned int is_toplevel : 1; /**< FALSE if we are a sub-config-file inside another one */ + + unsigned int allow_anonymous : 1; /**< TRUE to allow anonymous connections */ }; static Element* @@ -851,6 +853,20 @@ start_busconfig_child (BusConfigParser *parser, return TRUE; } + else if (element_type == ELEMENT_ALLOW_ANONYMOUS) + { + if (!check_no_attributes (parser, "allow_anonymous", attribute_names, attribute_values, error)) + return FALSE; + + if (push_element (parser, ELEMENT_ALLOW_ANONYMOUS) == NULL) + { + BUS_SET_OOM (error); + return FALSE; + } + + parser->allow_anonymous = TRUE; + return TRUE; + } else if (element_type == ELEMENT_SERVICEDIR) { if (!check_no_attributes (parser, "servicedir", attribute_names, attribute_values, error)) @@ -1994,6 +2010,7 @@ bus_config_parser_end_element (BusConfigParser *parser, case ELEMENT_ASSOCIATE: case ELEMENT_STANDARD_SESSION_SERVICEDIRS: case ELEMENT_STANDARD_SYSTEM_SERVICEDIRS: + case ELEMENT_ALLOW_ANONYMOUS: break; } @@ -2279,6 +2296,7 @@ bus_config_parser_content (BusConfigParser *parser, case ELEMENT_KEEP_UMASK: case ELEMENT_STANDARD_SESSION_SERVICEDIRS: case ELEMENT_STANDARD_SYSTEM_SERVICEDIRS: + case ELEMENT_ALLOW_ANONYMOUS: case ELEMENT_SELINUX: case ELEMENT_ASSOCIATE: if (all_whitespace (content)) @@ -2611,6 +2629,12 @@ bus_config_parser_get_keep_umask (BusConfigParser *parser) return parser->keep_umask; } +dbus_bool_t +bus_config_parser_get_allow_anonymous (BusConfigParser *parser) +{ + return parser->allow_anonymous; +} + const char * bus_config_parser_get_pidfile (BusConfigParser *parser) { diff --git a/bus/connection.c b/bus/connection.c index ab99fa5f..9159c898 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -575,12 +575,11 @@ cache_peer_loginfo_string (BusConnectionData *d, } if (!_dbus_string_append_printf (&loginfo_buf, "pid=%ld comm=\"", pid)) goto oom; - /* Ignore errors here */ - if (_dbus_command_for_pid (pid, &loginfo_buf, MAX_LOG_COMMAND_LEN, NULL)) - { - if (!_dbus_string_append_byte (&loginfo_buf, '"')) - goto oom; - } + /* Ignore errors here; we may not have permissions to read the + * proc file. */ + _dbus_command_for_pid (pid, &loginfo_buf, MAX_LOG_COMMAND_LEN, NULL); + if (!_dbus_string_append_byte (&loginfo_buf, '"')) + goto oom; } if (dbus_connection_get_windows_user (connection, &windows_sid)) diff --git a/bus/dbus-daemon.1.in b/bus/dbus-daemon.1.in index 8342600e..4b55ac29 100644 --- a/bus/dbus-daemon.1.in +++ b/bus/dbus-daemon.1.in @@ -430,7 +430,6 @@ your service. .PP The <policy> element has one of four attributes: -daemon.1.in .nf context="(default|mandatory)" at_console="(true|false)" @@ -496,9 +495,7 @@ The possible attributes of these elements are: .PP Examples: .nf - <deny send_interface="org.freedesktop.System" send_member="Reboot"/> - <deny receive_interface="org.freedesktop.System" receive_member="Reboot"/> - <deny own="org.freedesktop.System"/> + <deny send_destination="org.freedesktop.Service" send_interface="org.freedesktop.System" send_member="Reboot"/> <deny send_destination="org.freedesktop.System"/> <deny receive_sender="org.freedesktop.System"/> <deny user="john"/> diff --git a/bus/desktop-file.c b/bus/desktop-file.c index 2fe26a11..2ba77292 100644 --- a/bus/desktop-file.c +++ b/bus/desktop-file.c @@ -66,7 +66,7 @@ typedef struct #define VALID_KEY_CHAR 1 #define VALID_LOCALE_CHAR 2 -unsigned char valid[256] = { +static unsigned char valid[256] = { 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x3 , 0x2 , 0x0 , diff --git a/bus/driver.c b/bus/driver.c index c97bff5d..b5138067 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -1643,7 +1643,7 @@ bus_driver_handle_get_id (DBusConnection *connection, * frequency of use (but doesn't matter with only a few items * anyhow) */ -struct +static struct { const char *name; const char *in_args; diff --git a/bus/selinux.c b/bus/selinux.c index c0f6f4db..46a18a93 100644 --- a/bus/selinux.c +++ b/bus/selinux.c @@ -433,8 +433,18 @@ bus_selinux_check (BusSELinuxID *sender_sid, SELINUX_SID_FROM_BUS (bus_sid), target_class, requested, &aeref, auxdata) < 0) { - _dbus_verbose ("SELinux denying due to security policy.\n"); - return FALSE; + switch (errno) + { + case EACCES: + _dbus_verbose ("SELinux denying due to security policy.\n"); + return FALSE; + case EINVAL: + _dbus_verbose ("SELinux denying due to invalid security context.\n"); + return FALSE; + default: + _dbus_verbose ("SELinux denying due to: %s\n", _dbus_strerror (errno)); + return FALSE; + } } else return TRUE; diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index a960a991..947c0afe 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -448,7 +448,7 @@ _dbus_connection_queue_received_message_link (DBusConnection *connection, DBusList *link) { DBusPendingCall *pending; - dbus_int32_t reply_serial; + dbus_uint32_t reply_serial; DBusMessage *message; _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport)); @@ -459,7 +459,7 @@ _dbus_connection_queue_received_message_link (DBusConnection *connection, /* If this is a reply we're waiting on, remove timeout for it */ reply_serial = dbus_message_get_reply_serial (message); - if (reply_serial != -1) + if (reply_serial != 0) { pending = _dbus_hash_table_lookup_int (connection->pending_replies, reply_serial); @@ -1950,7 +1950,7 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *con if (dbus_message_get_serial (message) == 0) { serial = _dbus_connection_get_next_client_serial (connection); - _dbus_message_set_serial (message, serial); + dbus_message_set_serial (message, serial); if (client_serial) *client_serial = serial; } @@ -1963,7 +1963,7 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *con _dbus_verbose ("Message %p serial is %u\n", message, dbus_message_get_serial (message)); - _dbus_message_lock (message); + dbus_message_lock (message); /* Now we need to run an iteration to hopefully just write the messages * out immediately, and otherwise get them queued up @@ -2927,7 +2927,7 @@ dbus_connection_get_server_id (DBusConnection *connection) { char *id; - _dbus_return_val_if_fail (connection != NULL, FALSE); + _dbus_return_val_if_fail (connection != NULL, NULL); CONNECTION_LOCK (connection); id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport)); @@ -3208,7 +3208,7 @@ dbus_connection_send_with_reply (DBusConnection *connection, if (serial == 0) { serial = _dbus_connection_get_next_client_serial (connection); - _dbus_message_set_serial (message, serial); + dbus_message_set_serial (message, serial); } if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial)) @@ -3340,7 +3340,7 @@ dbus_connection_send_with_reply_and_block (DBusConnection *connection, * * @param connection the connection. */ -DBusDispatchStatus +static DBusDispatchStatus _dbus_connection_flush_unlocked (DBusConnection *connection) { /* We have to specify DBUS_ITERATION_DO_READING here because diff --git a/dbus/dbus-keyring.c b/dbus/dbus-keyring.c index de6a5ea4..8cc4048f 100644 --- a/dbus/dbus-keyring.c +++ b/dbus/dbus-keyring.c @@ -1075,7 +1075,7 @@ _dbus_keyring_test (void) dbus_error_init (&error); ring1 = _dbus_keyring_new_for_credentials (NULL, &context, &error); - _dbus_assert (ring1); + _dbus_assert (ring1 != NULL); _dbus_assert (error.name == NULL); id = _dbus_keyring_get_best_key (ring1, &error); @@ -1087,7 +1087,7 @@ _dbus_keyring_test (void) } ring2 = _dbus_keyring_new_for_credentials (NULL, &context, &error); - _dbus_assert (ring2); + _dbus_assert (ring2 != NULL); _dbus_assert (error.name == NULL); if (ring1->n_keys != ring2->n_keys) diff --git a/dbus/dbus-marshal-basic.c b/dbus/dbus-marshal-basic.c index 724d94b8..38fbe2d6 100644 --- a/dbus/dbus-marshal-basic.c +++ b/dbus/dbus-marshal-basic.c @@ -508,59 +508,74 @@ _dbus_marshal_read_basic (const DBusString *str, int *new_pos) { const char *str_data; - DBusBasicValue *vp; _dbus_assert (dbus_type_is_basic (type)); str_data = _dbus_string_get_const_data (str); - vp = value; + /* Below we volatile types to avoid aliasing issues; + * see http://bugs.freedesktop.org/show_bug.cgi?id=20137 + */ + switch (type) { case DBUS_TYPE_BYTE: - vp->byt = _dbus_string_get_byte (str, pos); + { + volatile unsigned char *vp = value; + *vp = (unsigned char) _dbus_string_get_byte (str, pos); (pos)++; + } break; case DBUS_TYPE_INT16: case DBUS_TYPE_UINT16: + { + volatile dbus_uint16_t *vp = value; pos = _DBUS_ALIGN_VALUE (pos, 2); - vp->u16 = *(dbus_uint16_t *)(str_data + pos); + *vp = *(dbus_uint16_t *)(str_data + pos); if (byte_order != DBUS_COMPILER_BYTE_ORDER) - vp->u16 = DBUS_UINT16_SWAP_LE_BE (vp->u16); + *vp = DBUS_UINT16_SWAP_LE_BE (*vp); pos += 2; + } break; case DBUS_TYPE_INT32: case DBUS_TYPE_UINT32: case DBUS_TYPE_BOOLEAN: + { + volatile dbus_uint32_t *vp = value; pos = _DBUS_ALIGN_VALUE (pos, 4); - vp->u32 = *(dbus_uint32_t *)(str_data + pos); + *vp = *(dbus_uint32_t *)(str_data + pos); if (byte_order != DBUS_COMPILER_BYTE_ORDER) - vp->u32 = DBUS_UINT32_SWAP_LE_BE (vp->u32); + *vp = DBUS_UINT32_SWAP_LE_BE (*vp); pos += 4; + } break; case DBUS_TYPE_INT64: case DBUS_TYPE_UINT64: case DBUS_TYPE_DOUBLE: + { + volatile dbus_uint64_t *vp = value; pos = _DBUS_ALIGN_VALUE (pos, 8); #ifdef DBUS_HAVE_INT64 if (byte_order != DBUS_COMPILER_BYTE_ORDER) - vp->u64 = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos)); + *vp = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos)); else - vp->u64 = *(dbus_uint64_t*)(str_data + pos); + *vp = *(dbus_uint64_t*)(str_data + pos); #else - vp->u64 = *(DBus8ByteStruct*) (str_data + pos); + *vp = *(DBus8ByteStruct*) (str_data + pos); swap_8_octets (vp, byte_order); #endif pos += 8; + } break; case DBUS_TYPE_STRING: case DBUS_TYPE_OBJECT_PATH: { int len; + volatile char **vp = value; len = _dbus_marshal_read_uint32 (str, pos, byte_order, &pos); - vp->str = (char*) str_data + pos; + *vp = (char*) str_data + pos; pos += len + 1; /* length plus nul */ } @@ -568,11 +583,12 @@ _dbus_marshal_read_basic (const DBusString *str, case DBUS_TYPE_SIGNATURE: { int len; + volatile char **vp = value; len = _dbus_string_get_byte (str, pos); pos += 1; - vp->str = (char*) str_data + pos; + *vp = (char*) str_data + pos; pos += len + 1; /* length plus nul */ } diff --git a/dbus/dbus-marshal-validate-util.c b/dbus/dbus-marshal-validate-util.c index 5365d6d3..ac901c38 100644 --- a/dbus/dbus-marshal-validate-util.c +++ b/dbus/dbus-marshal-validate-util.c @@ -227,7 +227,7 @@ _dbus_marshal_validate_test (void) "not a valid signature", "123", ".", - "(" + "(", "a{(ii)i}" /* https://bugs.freedesktop.org/show_bug.cgi?id=17803 */ }; diff --git a/dbus/dbus-marshal-validate.c b/dbus/dbus-marshal-validate.c index 35998cbb..78d55941 100644 --- a/dbus/dbus-marshal-validate.c +++ b/dbus/dbus-marshal-validate.c @@ -246,14 +246,15 @@ _dbus_validate_signature_with_reason (const DBusString *type_str, } } - if (last == DBUS_DICT_ENTRY_BEGIN_CHAR && - _dbus_type_is_valid (*p) && - !dbus_type_is_basic (*p)) + if (last == DBUS_DICT_ENTRY_BEGIN_CHAR) { - result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE; - goto out; + if (!(_dbus_type_is_valid (*p) && dbus_type_is_basic (*p))) + { + result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE; + goto out; + } } - + last = *p; ++p; } @@ -809,6 +810,77 @@ _dbus_validate_path (const DBusString *str, return TRUE; } +const char * +_dbus_validity_to_error_message (DBusValidity validity) +{ + switch (validity) + { + case DBUS_VALIDITY_UNKNOWN_OOM_ERROR: return "Out of memory"; + case DBUS_INVALID_FOR_UNKNOWN_REASON: return "Unknown reason"; + case DBUS_VALID_BUT_INCOMPLETE: return "Valid but incomplete"; + case DBUS_VALIDITY_UNKNOWN: return "Validity unknown"; + case DBUS_VALID: return "Valid"; + case DBUS_INVALID_UNKNOWN_TYPECODE: return "Unknown typecode"; + case DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE: return "Missing array element type"; + case DBUS_INVALID_SIGNATURE_TOO_LONG: return "Signature is too long"; + case DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION: return "Exceeded maximum array recursion"; + case DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION: return "Exceeded maximum struct recursion"; + case DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED: return "Struct ended but not started"; + case DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED: return "Struct started but not ended"; + case DBUS_INVALID_STRUCT_HAS_NO_FIELDS: return "Struct has no fields"; + case DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL: return "Alignment padding not null"; + case DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE: return "Boolean is not zero or one"; + case DBUS_INVALID_NOT_ENOUGH_DATA: return "Not enough data"; + case DBUS_INVALID_TOO_MUCH_DATA: return "Too much data"; + case DBUS_INVALID_BAD_BYTE_ORDER: return "Bad byte order"; + case DBUS_INVALID_BAD_PROTOCOL_VERSION: return "Bad protocol version"; + case DBUS_INVALID_BAD_MESSAGE_TYPE: return "Bad message type"; + case DBUS_INVALID_BAD_SERIAL: return "Bad serial"; + case DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH: return "Insane fields array length"; + case DBUS_INVALID_INSANE_BODY_LENGTH: return "Insane body length"; + case DBUS_INVALID_MESSAGE_TOO_LONG: return "Message too long"; + case DBUS_INVALID_HEADER_FIELD_CODE: return "Header field code"; + case DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE: return "Header field has wrong type"; + case DBUS_INVALID_USES_LOCAL_INTERFACE: return "Uses local interface"; + case DBUS_INVALID_USES_LOCAL_PATH: return "Uses local path"; + case DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE: return "Header field appears twice"; + case DBUS_INVALID_BAD_DESTINATION: return "Bad destination"; + case DBUS_INVALID_BAD_INTERFACE: return "Bad interface"; + case DBUS_INVALID_BAD_MEMBER: return "Bad member"; + case DBUS_INVALID_BAD_ERROR_NAME: return "Bad error name"; + case DBUS_INVALID_BAD_SENDER: return "Bad sender"; + case DBUS_INVALID_MISSING_PATH: return "Missing path"; + case DBUS_INVALID_MISSING_INTERFACE: return "Missing interface"; + case DBUS_INVALID_MISSING_MEMBER: return "Missing member"; + case DBUS_INVALID_MISSING_ERROR_NAME: return "Missing error name"; + case DBUS_INVALID_MISSING_REPLY_SERIAL: return "Missing reply serial"; + case DBUS_INVALID_LENGTH_OUT_OF_BOUNDS: return "Length out of bounds"; + case DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM: return "Array length exceeds maximum"; + case DBUS_INVALID_BAD_PATH: return "Bad path"; + case DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS: return "Signature length out of bounds"; + case DBUS_INVALID_BAD_UTF8_IN_STRING: return "Bad utf8 in string"; + case DBUS_INVALID_ARRAY_LENGTH_INCORRECT: return "Array length incorrect"; + case DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS: return "Variant signature length out of bounds"; + case DBUS_INVALID_VARIANT_SIGNATURE_BAD: return "Variant signature bad"; + case DBUS_INVALID_VARIANT_SIGNATURE_EMPTY: return "Variant signature empty"; + case DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES: return "Variant signature specifies multiple values"; + case DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL: return "Variant signature missing nul"; + case DBUS_INVALID_STRING_MISSING_NUL: return "String missing nul"; + case DBUS_INVALID_SIGNATURE_MISSING_NUL: return "Signature missing nul"; + case DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION: return "Exceeded maximum dict entry recursion"; + case DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED: return "Dict entry ended but not started"; + case DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED: return "Dict entry started but not ended"; + case DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS: return "Dict entry has no fields"; + case DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD: return "Dict entry has only one field"; + case DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS: return "Dict entry has too many fields"; + case DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY: return "Dict entry not inside array"; + case DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE: return "Dict key must be basic type"; + + default: + return "Invalid"; + } +} + /** * Checks that the given range of the string is a valid interface name * in the D-Bus protocol. This includes a length restriction and an diff --git a/dbus/dbus-marshal-validate.h b/dbus/dbus-marshal-validate.h index f5b168f5..d09acc60 100644 --- a/dbus/dbus-marshal-validate.h +++ b/dbus/dbus-marshal-validate.h @@ -131,6 +131,8 @@ DBusValidity _dbus_validate_body_with_reason (const DBusString *expected_si int value_pos, int len); +const char *_dbus_validity_to_error_message (DBusValidity validity); + dbus_bool_t _dbus_validate_path (const DBusString *str, int start, int len); diff --git a/dbus/dbus-message-factory.c b/dbus/dbus-message-factory.c index ceffc764..8550ee86 100644 --- a/dbus/dbus-message-factory.c +++ b/dbus/dbus-message-factory.c @@ -222,8 +222,8 @@ generate_from_message (DBusString *data, DBusValidity *expected_validity, DBusMessage *message) { - _dbus_message_set_serial (message, 1); - _dbus_message_lock (message); + dbus_message_set_serial (message, 1); + dbus_message_lock (message); *expected_validity = DBUS_VALID; diff --git a/dbus/dbus-message-internal.h b/dbus/dbus-message-internal.h index 76615859..2e995b47 100644 --- a/dbus/dbus-message-internal.h +++ b/dbus/dbus-message-internal.h @@ -37,8 +37,6 @@ void _dbus_message_get_network_data (DBusMessage *message, void _dbus_message_lock (DBusMessage *message); void _dbus_message_unlock (DBusMessage *message); -void _dbus_message_set_serial (DBusMessage *message, - dbus_uint32_t serial); dbus_bool_t _dbus_message_add_size_counter (DBusMessage *message, DBusCounter *counter); void _dbus_message_add_size_counter_link (DBusMessage *message, diff --git a/dbus/dbus-message-util.c b/dbus/dbus-message-util.c index 0fa010cc..46cbe4e3 100644 --- a/dbus/dbus-message-util.c +++ b/dbus/dbus-message-util.c @@ -949,7 +949,7 @@ _dbus_message_test (const char *test_data_dir) "TestMethod")); _dbus_assert (strcmp (dbus_message_get_path (message), "/org/freedesktop/TestPath") == 0); - _dbus_message_set_serial (message, 1234); + dbus_message_set_serial (message, 1234); /* string length including nul byte not a multiple of 4 */ if (!dbus_message_set_sender (message, "org.foo.bar1")) @@ -1041,7 +1041,7 @@ _dbus_message_test (const char *test_data_dir) "/org/freedesktop/TestPath", "Foo.TestInterface", "TestMethod"); - _dbus_message_set_serial (message, 1); + dbus_message_set_serial (message, 1); dbus_message_set_reply_serial (message, 5678); v_INT16 = -0x123; @@ -1172,7 +1172,7 @@ _dbus_message_test (const char *test_data_dir) dbus_message_unref (copy); /* Message loader test */ - _dbus_message_lock (message); + dbus_message_lock (message); loader = _dbus_message_loader_new (); /* check ref/unref */ @@ -1226,6 +1226,7 @@ _dbus_message_test (const char *test_data_dir) DBusError error = DBUS_ERROR_INIT; char *marshalled = NULL; int len = 0; + char garbage_header[DBUS_MINIMUM_HEADER_SIZE] = "xxx"; if (!dbus_message_marshal (message, &marshalled, &len)) _dbus_assert_not_reached ("failed to marshal message"); @@ -1233,6 +1234,7 @@ _dbus_message_test (const char *test_data_dir) _dbus_assert (len != 0); _dbus_assert (marshalled != NULL); + _dbus_assert (dbus_message_demarshal_bytes_needed (marshalled, len) == len); message2 = dbus_message_demarshal (marshalled, len, &error); _dbus_assert (message2 != NULL); @@ -1255,6 +1257,14 @@ _dbus_message_test (const char *test_data_dir) _dbus_assert (message2 == NULL); _dbus_assert (dbus_error_is_set (&error)); dbus_error_free (&error); + + /* Bytes needed to demarshal empty message: 0 (more) */ + + _dbus_assert (dbus_message_demarshal_bytes_needed ("", 0) == 0); + + /* Bytes needed to demarshal invalid message: -1 (error). */ + + _dbus_assert (dbus_message_demarshal_bytes_needed (garbage_header, DBUS_MINIMUM_HEADER_SIZE) == -1); } dbus_message_unref (message); diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index e2c4771e..edae4258 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -142,7 +142,7 @@ _dbus_message_byteswap (DBusMessage *message) * Gets the data to be sent over the network for this message. * The header and then the body should be written out. * This function is guaranteed to always return the same - * data once a message is locked (with _dbus_message_lock()). + * data once a message is locked (with dbus_message_lock()). * * @param message the message. * @param header return location for message header data. @@ -163,16 +163,19 @@ _dbus_message_get_network_data (DBusMessage *message, * Sets the serial number of a message. * This can only be done once on a message. * + * DBusConnection will automatically set the serial to an appropriate value + * when the message is sent; this function is only needed when encapsulating + * messages in another protocol, or otherwise bypassing DBusConnection. + * * @param message the message * @param serial the serial */ -void -_dbus_message_set_serial (DBusMessage *message, - dbus_uint32_t serial) +void +dbus_message_set_serial (DBusMessage *message, + dbus_uint32_t serial) { - _dbus_assert (message != NULL); - _dbus_assert (!message->locked); - _dbus_assert (dbus_message_get_serial (message) == 0); + _dbus_return_if_fail (message != NULL); + _dbus_return_if_fail (!message->locked); _dbus_header_set_serial (&message->header, serial); } @@ -277,12 +280,13 @@ _dbus_message_remove_size_counter (DBusMessage *message, * reference to a message in the outgoing queue and change it * underneath us. Messages are locked when they enter the outgoing * queue (dbus_connection_send_message()), and the library complains - * if the message is modified while locked. + * if the message is modified while locked. This function may also + * called externally, for applications wrapping D-Bus in another protocol. * * @param message the message to lock. */ void -_dbus_message_lock (DBusMessage *message) +dbus_message_lock (DBusMessage *message) { if (!message->locked) { @@ -3941,7 +3945,7 @@ dbus_message_marshal (DBusMessage *msg, _dbus_return_val_if_fail (msg != NULL, FALSE); _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE); _dbus_return_val_if_fail (len_p != NULL, FALSE); - + if (!_dbus_string_init (&tmp)) return FALSE; @@ -4023,6 +4027,57 @@ dbus_message_demarshal (const char *str, return NULL; } +/** + * Returns the number of bytes required to be in the buffer to demarshal a + * D-Bus message. + * + * Generally, this function is only useful for encapsulating D-Bus messages in + * a different protocol. + * + * @param str data to be marshalled + * @param len the length of str + * @param error the location to save errors to + * @returns -1 if there was no valid data to be demarshalled, 0 if there wasn't enough data to determine how much should be demarshalled. Otherwise returns the number of bytes to be demarshalled + * + */ +int +dbus_message_demarshal_bytes_needed(const char *buf, + int len) +{ + DBusString str; + int byte_order, fields_array_len, header_len, body_len; + DBusValidity validity = DBUS_VALID; + int have_message; + + if (!buf || len < DBUS_MINIMUM_HEADER_SIZE) + return 0; + + if (len > DBUS_MAXIMUM_MESSAGE_LENGTH) + len = DBUS_MAXIMUM_MESSAGE_LENGTH; + _dbus_string_init_const_len (&str, buf, len); + + validity = DBUS_VALID; + have_message + = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH, + &validity, &byte_order, + &fields_array_len, + &header_len, + &body_len, + &str, 0, + len); + _dbus_string_free (&str); + + if (validity == DBUS_VALID) + { + _dbus_assert(have_message); + return header_len + body_len; + } + else + { + return -1; /* broken! */ + } +} + /** @} */ /* tests in dbus-message-util.c */ diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h index 1bf7d0c2..2e29fef0 100644 --- a/dbus/dbus-message.h +++ b/dbus/dbus-message.h @@ -131,6 +131,8 @@ dbus_bool_t dbus_message_has_sender (DBusMessage *message, dbus_bool_t dbus_message_has_signature (DBusMessage *message, const char *signature); dbus_uint32_t dbus_message_get_serial (DBusMessage *message); +void dbus_message_set_serial (DBusMessage *message, + dbus_uint32_t serial); dbus_bool_t dbus_message_set_reply_serial (DBusMessage *message, dbus_uint32_t reply_serial); dbus_uint32_t dbus_message_get_reply_serial (DBusMessage *message); @@ -196,6 +198,7 @@ dbus_bool_t dbus_message_iter_open_container (DBusMessageIter *iter, dbus_bool_t dbus_message_iter_close_container (DBusMessageIter *iter, DBusMessageIter *sub); +void dbus_message_lock (DBusMessage *message); dbus_bool_t dbus_set_error_from_message (DBusError *error, DBusMessage *message); @@ -220,6 +223,9 @@ DBusMessage* dbus_message_demarshal (const char *str, int len, DBusError *error); +int dbus_message_demarshal_bytes_needed (const char *str, + int len); + /** @} */ DBUS_END_DECLS diff --git a/dbus/dbus-signature.c b/dbus/dbus-signature.c index a8864f8b..c7f8d0e3 100644 --- a/dbus/dbus-signature.c +++ b/dbus/dbus-signature.c @@ -233,12 +233,18 @@ dbus_signature_validate (const char *signature, { DBusString str; + DBusValidity reason; _dbus_string_init_const (&str, signature); - if (_dbus_validate_signature (&str, 0, _dbus_string_get_length (&str))) + reason = _dbus_validate_signature_with_reason (&str, 0, _dbus_string_get_length (&str)); + + if (reason == DBUS_VALID) return TRUE; - dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Corrupt type signature"); - return FALSE; + else + { + dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, _dbus_validity_to_error_message (reason)); + return FALSE; + } } /** diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index ccb84832..29d234a4 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -758,6 +758,7 @@ _dbus_connect_tcp_socket (const char *host, const char *family, DBusError *error) { + int saved_errno = 0; int fd = -1, res; struct addrinfo hints; struct addrinfo *ai, *tmp; @@ -783,7 +784,7 @@ _dbus_connect_tcp_socket (const char *host, else { dbus_set_error (error, - _dbus_error_from_errno (errno), + DBUS_ERROR_BAD_ADDRESS, "Unknown address family %s", family); return -1; } @@ -814,6 +815,7 @@ _dbus_connect_tcp_socket (const char *host, if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) { + saved_errno = errno; _dbus_close(fd, NULL); fd = -1; tmp = tmp->ai_next; @@ -827,9 +829,9 @@ _dbus_connect_tcp_socket (const char *host, if (fd == -1) { dbus_set_error (error, - _dbus_error_from_errno (errno), + _dbus_error_from_errno (saved_errno), "Failed to connect to socket \"%s:%s\" %s", - host, port, _dbus_strerror(errno)); + host, port, _dbus_strerror(saved_errno)); return -1; } @@ -867,6 +869,7 @@ _dbus_listen_tcp_socket (const char *host, int **fds_p, DBusError *error) { + int saved_errno; int nlisten_fd = 0, *listen_fd = NULL, res, i; struct addrinfo hints; struct addrinfo *ai, *tmp; @@ -885,7 +888,7 @@ _dbus_listen_tcp_socket (const char *host, else { dbus_set_error (error, - _dbus_error_from_errno (errno), + DBUS_ERROR_BAD_ADDRESS, "Unknown address family %s", family); return -1; } @@ -917,8 +920,9 @@ _dbus_listen_tcp_socket (const char *host, if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) { + saved_errno = errno; _dbus_close(fd, NULL); - if (errno == EADDRINUSE) + if (saved_errno == EADDRINUSE) { /* Depending on kernel policy, it may or may not be neccessary to bind to both IPv4 & 6 addresses @@ -926,28 +930,30 @@ _dbus_listen_tcp_socket (const char *host, tmp = tmp->ai_next; continue; } - dbus_set_error (error, _dbus_error_from_errno (errno), + dbus_set_error (error, _dbus_error_from_errno (saved_errno), "Failed to bind socket \"%s:%s\": %s", - host ? host : "*", port, _dbus_strerror (errno)); + host ? host : "*", port, _dbus_strerror (saved_errno)); goto failed; } if (listen (fd, 30 /* backlog */) < 0) { + saved_errno = errno; _dbus_close (fd, NULL); - dbus_set_error (error, _dbus_error_from_errno (errno), + dbus_set_error (error, _dbus_error_from_errno (saved_errno), "Failed to listen on socket \"%s:%s\": %s", - host ? host : "*", port, _dbus_strerror (errno)); + host ? host : "*", port, _dbus_strerror (saved_errno)); goto failed; } newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1)); if (!newlisten_fd) { + saved_errno = errno; _dbus_close (fd, NULL); - dbus_set_error (error, _dbus_error_from_errno (errno), + dbus_set_error (error, _dbus_error_from_errno (saved_errno), "Failed to allocate file handle array: %s", - _dbus_strerror (errno)); + _dbus_strerror (saved_errno)); goto failed; } listen_fd = newlisten_fd; diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c index 03928044..f1e20334 100644 --- a/dbus/dbus-sysdeps-util-unix.c +++ b/dbus/dbus-sysdeps-util-unix.c @@ -44,6 +44,7 @@ #include <dirent.h> #include <sys/un.h> #include <syslog.h> +#include <syslog.h> #ifdef HAVE_LIBAUDIT #include <sys/prctl.h> #include <sys/capability.h> @@ -1233,4 +1234,4 @@ fail: _dbus_string_free (&cmdline); _dbus_string_free (&path); return FALSE; -}
\ No newline at end of file +} diff --git a/dbus/dbus-transport-socket.c b/dbus/dbus-transport-socket.c index 10b671c2..6d7c89cd 100644 --- a/dbus/dbus-transport-socket.c +++ b/dbus/dbus-transport-socket.c @@ -537,7 +537,7 @@ do_writing (DBusTransport *transport) message = _dbus_connection_get_message_to_send (transport->connection); _dbus_assert (message != NULL); - _dbus_message_lock (message); + dbus_message_lock (message); #if 0 _dbus_verbose ("writing message %p\n", message); diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c index 90291980..35b7027d 100644 --- a/dbus/dbus-transport.c +++ b/dbus/dbus-transport.c @@ -242,7 +242,7 @@ check_address (const char *address, DBusError *error) _dbus_assert (*address != '\0'); if (!dbus_parse_address (address, &entries, &len, error)) - return FALSE; /* not a valid address */ + return NULL; /* not a valid address */ for (i = 0; i < len; i++) { diff --git a/test/name-test/test-names.c b/test/name-test/test-names.c index f4b0ba08..b09f3638 100644 --- a/test/name-test/test-names.c +++ b/test/name-test/test-names.c @@ -37,7 +37,7 @@ typedef struct { int expected_queue[NUM_CONN]; } CommandAndResult; -CommandAndResult test_data[] = { +static CommandAndResult test_data[] = { {ADD_CONNECTION, 0, ALLOW_REPLACEMENT | REPLACE_EXISTING, PRIMARY_OWNER, {0,-1,-1,-1}}, {ADD_CONNECTION, 0, REPLACE_EXISTING, diff --git a/test/name-test/test-shutdown.c b/test/name-test/test-shutdown.c index c50ef4b6..e76c1ea2 100644 --- a/test/name-test/test-shutdown.c +++ b/test/name-test/test-shutdown.c @@ -11,7 +11,7 @@ die (const char *message) } static void -open_destroy_shared_session_bus_connection () +open_destroy_shared_session_bus_connection (void) { DBusError error; DBusConnection *connection; diff --git a/test/name-test/tmp-session-like-system.conf b/test/name-test/tmp-session-like-system.conf index 0818109a..29ab115f 100644 --- a/test/name-test/tmp-session-like-system.conf +++ b/test/name-test/tmp-session-like-system.conf @@ -8,6 +8,10 @@ <!-- Our well-known bus type, don't change this --> <type>session</type> + <!-- If we fork, keep the user's original umask to avoid affecting + the behavior of child processes. --> + <keep_umask/> + <syslog/> <listen>unix:tmpdir=/tmp</listen> diff --git a/tools/dbus-launch-x11.c b/tools/dbus-launch-x11.c index 442e9ba2..b1824181 100644 --- a/tools/dbus-launch-x11.c +++ b/tools/dbus-launch-x11.c @@ -361,9 +361,9 @@ set_address_in_x11(char *address, pid_t pid) } /* Create our window */ - wid = XCreateSimpleWindow (xdisplay, RootWindow (xdisplay, 0), -20, -20, 10, 10, - 0, WhitePixel (xdisplay, 0), - BlackPixel (xdisplay, 0)); + wid = XCreateWindow (xdisplay, RootWindow (xdisplay, 0), -20, -20, 10, 10, + 0, CopyFromParent, InputOnly, CopyFromParent, + 0, NULL); verbose ("Created window %d\n", wid); /* Save the property in the window */ diff --git a/tools/dbus-launch.c b/tools/dbus-launch.c index 139d0aaf..9c47d7e3 100644 --- a/tools/dbus-launch.c +++ b/tools/dbus-launch.c @@ -335,7 +335,7 @@ do_waitpid (pid_t pid) static pid_t bus_pid_to_kill = -1; static void -kill_bus() +kill_bus(void) { verbose ("Killing message bus and exiting babysitter\n"); kill (bus_pid_to_kill, SIGTERM); diff --git a/tools/dbus-monitor.c b/tools/dbus-monitor.c index ee03d854..cbd7a489 100644 --- a/tools/dbus-monitor.c +++ b/tools/dbus-monitor.c @@ -195,7 +195,7 @@ usage (char *name, int ecode) exit (ecode); } -dbus_bool_t sigint_received = FALSE; +static dbus_bool_t sigint_received = FALSE; static void sigint_handler (int signum) |