Control: retitle -1 buster-pu: package dbus/1.12.20-0+deb10u1 On Sat, 20 Jun 2020 at 20:26:24 +0100, Adam D. Barratt wrote: > On Tue, 2020-06-02 at 21:22 +0100, Simon McVittie wrote: > > dbus 1.12.18 fixes a local denial of service vulnerability for which > > the Security Team have indicated they do not intend to issue a DSA. > > > > If possible I would like to use upstream 1.12.x versions of dbus for > > buster (security and) stable updates, similar to the policy used in > > stretch and jessie. This branch includes security fixes and selected > > non-intrusive bug fixes (and unfortunately also the usual Autotools > > noise). > > > > That sounds OK to me, but will need the usual KiBi-ack due to the udeb.
I have now released 1.12.20 upstream. This fixes a long-standing use-after-free if two usernames have the same numeric uid (which is potentially a security fix if you have such usernames), and a regression on Solaris derivatives. Does this still look OK for buster-pu? (Diff since the version you already saw attached - I haven't bothered to filter out the Autotools noise this time, because there is much less of it.) I've asked the security team whether they will now want a DSA for the use-after-free, but I suspect the answer will be "no, talk to the stable release team" so I'm asking preemptively. For #962068, dbus 1.10.30 -> 1.10.32 has a remarkably similar diff (it's a cherry-pick of the same commits as in 1.12.20). I assume the judgement on that from both the security team and the stable release team will be the same as for buster, unless the stretch EOL has already happened by the time we get there. smcv
diff --git a/Makefile.in b/Makefile.in index 2ef174ae..c3973629 100644 --- a/Makefile.in +++ b/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # aminclude_static.am generated automatically by Autoconf -# from AX_AM_MACROS_STATIC on Tue Jun 2 13:56:47 BST 2020 +# from AX_AM_MACROS_STATIC on Thu Jul 2 11:10:39 BST 2020 VPATH = @srcdir@ am__is_gnu_make = { \ diff --git a/NEWS b/NEWS index a38c5992..2fca1455 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,27 @@ +dbus 1.12.20 (2020-07-02) +========================= + +The “temporary nemesis” release. + +Maybe security fixes: + +• On Unix, avoid a use-after-free if two usernames have the same + numeric uid. In older versions this could lead to a crash (denial of + service) or other undefined behaviour, possibly including incorrect + authorization decisions if <policy group=...> is used. + Like Unix filesystems, D-Bus' model of identity cannot distinguish + between users of different names with the same numeric uid, so this + configuration is not advisable on systems where D-Bus will be used. + Thanks to Daniel Onaca. + (dbus#305, dbus!166; Simon McVittie) + +Other fixes: + +• On Solaris and its derivatives, if a cmsg header is truncated, ensure + that we do not overrun the buffer used for fd-passing, even if the + kernel tells us to. + (dbus#304, dbus!165; Andy Fiddaman) + dbus 1.12.18 (2020-06-02) ========================= diff --git a/aminclude_static.am b/aminclude_static.am index 7b415587..3dabd131 100644 --- a/aminclude_static.am +++ b/aminclude_static.am @@ -1,6 +1,6 @@ # aminclude_static.am generated automatically by Autoconf -# from AX_AM_MACROS_STATIC on Tue Jun 2 13:56:47 BST 2020 +# from AX_AM_MACROS_STATIC on Thu Jul 2 11:10:39 BST 2020 # Code coverage diff --git a/bus/Makefile.in b/bus/Makefile.in index 5367203e..fa44d2b6 100644 --- a/bus/Makefile.in +++ b/bus/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # aminclude_static.am generated automatically by Autoconf -# from AX_AM_MACROS_STATIC on Tue Jun 2 13:56:47 BST 2020 +# from AX_AM_MACROS_STATIC on Thu Jul 2 11:10:39 BST 2020 VPATH = @srcdir@ diff --git a/configure b/configure index c1b736f4..38db1dd4 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for dbus 1.12.18. +# Generated by GNU Autoconf 2.69 for dbus 1.12.20. # # Report bugs to <https://bugs.freedesktop.org/enter_bug.cgi?product=dbus>. # @@ -591,8 +591,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='dbus' PACKAGE_TARNAME='dbus' -PACKAGE_VERSION='1.12.18' -PACKAGE_STRING='dbus 1.12.18' +PACKAGE_VERSION='1.12.20' +PACKAGE_STRING='dbus 1.12.20' PACKAGE_BUGREPORT='https://bugs.freedesktop.org/enter_bug.cgi?product=dbus' PACKAGE_URL='' @@ -1579,7 +1579,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures dbus 1.12.18 to adapt to many kinds of systems. +\`configure' configures dbus 1.12.20 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1654,7 +1654,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of dbus 1.12.18:";; + short | recursive ) echo "Configuration of dbus 1.12.20:";; esac cat <<\_ACEOF @@ -1881,7 +1881,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -dbus configure 1.12.18 +dbus configure 1.12.20 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2657,7 +2657,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by dbus $as_me 1.12.18, which was +It was created by dbus $as_me 1.12.20, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3603,7 +3603,7 @@ fi # Define the identity of the package. PACKAGE='dbus' - VERSION='1.12.18' + VERSION='1.12.20' cat >>confdefs.h <<_ACEOF @@ -3903,7 +3903,7 @@ LT_CURRENT=22 ## increment any time the source changes; set to ## 0 if you increment CURRENT -LT_REVISION=12 +LT_REVISION=13 ## increment if any interfaces have been added; set to 0 ## if any interfaces have been changed or removed. removal has @@ -3918,8 +3918,8 @@ SOVERSION=`expr ${LT_CURRENT} - ${LT_AGE}` DBUS_MAJOR_VERSION=1 DBUS_MINOR_VERSION=12 -DBUS_MICRO_VERSION=18 -DBUS_VERSION=1.12.18 +DBUS_MICRO_VERSION=20 +DBUS_VERSION=1.12.20 @@ -29015,7 +29015,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by dbus $as_me 1.12.18, which was +This file was extended by dbus $as_me 1.12.20, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -29081,7 +29081,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -dbus config.status 1.12.18 +dbus config.status 1.12.20 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 0601c421..3bb9cceb 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.63]) m4_define([dbus_major_version], [1]) m4_define([dbus_minor_version], [12]) -m4_define([dbus_micro_version], [18]) +m4_define([dbus_micro_version], [20]) m4_define([dbus_version], [dbus_major_version.dbus_minor_version.dbus_micro_version]) AC_INIT([dbus],[dbus_version],[https://bugs.freedesktop.org/enter_bug.cgi?product=dbus],[dbus]) @@ -42,7 +42,7 @@ LT_CURRENT=22 ## increment any time the source changes; set to ## 0 if you increment CURRENT -LT_REVISION=12 +LT_REVISION=13 ## increment if any interfaces have been added; set to 0 ## if any interfaces have been changed or removed. removal has diff --git a/dbus/Makefile.in b/dbus/Makefile.in index be51f012..6ea752ee 100644 --- a/dbus/Makefile.in +++ b/dbus/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # aminclude_static.am generated automatically by Autoconf -# from AX_AM_MACROS_STATIC on Tue Jun 2 13:56:47 BST 2020 +# from AX_AM_MACROS_STATIC on Thu Jul 2 11:10:39 BST 2020 diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index f9dc2a6e..e511afc5 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -441,13 +441,32 @@ _dbus_read_socket_with_unix_fds (DBusSocket fd, size_t i; int *payload = (int *) CMSG_DATA (cm); size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0)); - size_t payload_len_fds = payload_len_bytes / sizeof (int); + size_t payload_len_fds; size_t fds_to_use; /* Every unsigned int fits in a size_t without truncation, so * casting (size_t) *n_fds is OK */ _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (unsigned int)); + if ((m.msg_flags & MSG_CTRUNC) && CMSG_NXTHDR(&m, cm) == NULL && + (char *) payload + payload_len_bytes > + (char *) m.msg_control + m.msg_controllen) + { + /* This is the last cmsg in a truncated message and using + * cmsg_len would apparently overrun the allocated buffer. + * Some operating systems (illumos and Solaris are known) do + * not adjust cmsg_len in the last cmsg when truncation occurs. + * Adjust the payload length here. The calculation for + * payload_len_fds below will discard any trailing bytes that + * belong to an incomplete file descriptor - the kernel will + * have already closed that (at least for illumos and Solaris) + */ + payload_len_bytes = m.msg_controllen - + ((char *) payload - (char *) m.msg_control); + } + + payload_len_fds = payload_len_bytes / sizeof (int); + if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds)) { /* The fds in the payload will fit in our buffer */ diff --git a/dbus/dbus-sysdeps-unix.h b/dbus/dbus-sysdeps-unix.h index 8d3df2d6..830d5cd0 100644 --- a/dbus/dbus-sysdeps-unix.h +++ b/dbus/dbus-sysdeps-unix.h @@ -105,6 +105,7 @@ typedef struct DBusGroupInfo DBusGroupInfo; */ struct DBusUserInfo { + size_t refcount; /**< Reference count */ dbus_uid_t uid; /**< UID */ dbus_gid_t primary_gid; /**< GID */ dbus_gid_t *group_ids; /**< Groups IDs, *including* above primary group */ @@ -118,6 +119,7 @@ struct DBusUserInfo */ struct DBusGroupInfo { + size_t refcount; /**< Reference count */ dbus_gid_t gid; /**< GID */ char *groupname; /**< Group name */ }; diff --git a/dbus/dbus-userdb-util.c b/dbus/dbus-userdb-util.c index 44a1a78c..170d233e 100644 --- a/dbus/dbus-userdb-util.c +++ b/dbus/dbus-userdb-util.c @@ -38,6 +38,15 @@ * @{ */ +static DBusGroupInfo * +_dbus_group_info_ref (DBusGroupInfo *info) +{ + _dbus_assert (info->refcount > 0); + _dbus_assert (info->refcount < SIZE_MAX); + info->refcount++; + return info; +} + /** * Checks to see if the UID sent in is the console user * @@ -240,9 +249,9 @@ _dbus_get_user_id_and_primary_group (const DBusString *username, * @param gid the group ID or #DBUS_GID_UNSET * @param groupname group name or #NULL * @param error error to fill in - * @returns the entry in the database + * @returns the entry in the database (borrowed, do not free) */ -DBusGroupInfo* +const DBusGroupInfo * _dbus_user_database_lookup_group (DBusUserDatabase *db, dbus_gid_t gid, const DBusString *groupname, @@ -287,13 +296,14 @@ _dbus_user_database_lookup_group (DBusUserDatabase *db, dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); return NULL; } + info->refcount = 1; if (gid != DBUS_GID_UNSET) { if (!_dbus_group_info_fill_gid (info, gid, error)) { _DBUS_ASSERT_ERROR_IS_SET (error); - _dbus_group_info_free_allocated (info); + _dbus_group_info_unref (info); return NULL; } } @@ -302,7 +312,7 @@ _dbus_user_database_lookup_group (DBusUserDatabase *db, if (!_dbus_group_info_fill (info, groupname, error)) { _DBUS_ASSERT_ERROR_IS_SET (error); - _dbus_group_info_free_allocated (info); + _dbus_group_info_unref (info); return NULL; } } @@ -311,23 +321,37 @@ _dbus_user_database_lookup_group (DBusUserDatabase *db, gid = DBUS_GID_UNSET; groupname = NULL; - if (!_dbus_hash_table_insert_uintptr (db->groups, info->gid, info)) + if (_dbus_hash_table_insert_uintptr (db->groups, info->gid, info)) + { + _dbus_group_info_ref (info); + } + else { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); - _dbus_group_info_free_allocated (info); + _dbus_group_info_unref (info); return NULL; } - if (!_dbus_hash_table_insert_string (db->groups_by_name, - info->groupname, - info)) + if (_dbus_hash_table_insert_string (db->groups_by_name, + info->groupname, + info)) + { + _dbus_group_info_ref (info); + } + else { _dbus_hash_table_remove_uintptr (db->groups, info->gid); + _dbus_group_info_unref (info); dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); return NULL; } - + + /* Release the original reference */ + _dbus_group_info_unref (info); + + /* Return a borrowed reference to the DBusGroupInfo owned by the + * two hash tables */ return info; } } diff --git a/dbus/dbus-userdb.c b/dbus/dbus-userdb.c index 4c42b7dd..10434bbb 100644 --- a/dbus/dbus-userdb.c +++ b/dbus/dbus-userdb.c @@ -35,34 +35,57 @@ * @{ */ +static DBusUserInfo * +_dbus_user_info_ref (DBusUserInfo *info) +{ + _dbus_assert (info->refcount > 0); + _dbus_assert (info->refcount < SIZE_MAX); + info->refcount++; + return info; +} + /** - * Frees the given #DBusUserInfo's members with _dbus_user_info_free() + * Decrements the reference count. If it reaches 0, + * frees the given #DBusUserInfo's members with _dbus_user_info_free() * and also calls dbus_free() on the block itself * * @param info the info */ void -_dbus_user_info_free_allocated (DBusUserInfo *info) +_dbus_user_info_unref (DBusUserInfo *info) { if (info == NULL) /* hash table will pass NULL */ return; + _dbus_assert (info->refcount > 0); + _dbus_assert (info->refcount < SIZE_MAX); + + if (--info->refcount > 0) + return; + _dbus_user_info_free (info); dbus_free (info); } /** - * Frees the given #DBusGroupInfo's members with _dbus_group_info_free() + * Decrements the reference count. If it reaches 0, + * frees the given #DBusGroupInfo's members with _dbus_group_info_free() * and also calls dbus_free() on the block itself * * @param info the info */ void -_dbus_group_info_free_allocated (DBusGroupInfo *info) +_dbus_group_info_unref (DBusGroupInfo *info) { if (info == NULL) /* hash table will pass NULL */ return; + _dbus_assert (info->refcount > 0); + _dbus_assert (info->refcount < SIZE_MAX); + + if (--info->refcount > 0) + return; + _dbus_group_info_free (info); dbus_free (info); } @@ -122,9 +145,9 @@ _dbus_is_a_number (const DBusString *str, * @param uid the user ID or #DBUS_UID_UNSET * @param username username or #NULL * @param error error to fill in - * @returns the entry in the database + * @returns the entry in the database (borrowed, do not free) */ -DBusUserInfo* +const DBusUserInfo * _dbus_user_database_lookup (DBusUserDatabase *db, dbus_uid_t uid, const DBusString *username, @@ -170,13 +193,14 @@ _dbus_user_database_lookup (DBusUserDatabase *db, dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); return NULL; } + info->refcount = 1; if (uid != DBUS_UID_UNSET) { if (!_dbus_user_info_fill_uid (info, uid, error)) { _DBUS_ASSERT_ERROR_IS_SET (error); - _dbus_user_info_free_allocated (info); + _dbus_user_info_unref (info); return NULL; } } @@ -185,7 +209,7 @@ _dbus_user_database_lookup (DBusUserDatabase *db, if (!_dbus_user_info_fill (info, username, error)) { _DBUS_ASSERT_ERROR_IS_SET (error); - _dbus_user_info_free_allocated (info); + _dbus_user_info_unref (info); return NULL; } } @@ -195,22 +219,35 @@ _dbus_user_database_lookup (DBusUserDatabase *db, username = NULL; /* insert into hash */ - if (!_dbus_hash_table_insert_uintptr (db->users, info->uid, info)) + if (_dbus_hash_table_insert_uintptr (db->users, info->uid, info)) + { + _dbus_user_info_ref (info); + } + else { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); - _dbus_user_info_free_allocated (info); + _dbus_user_info_unref (info); return NULL; } - if (!_dbus_hash_table_insert_string (db->users_by_name, - info->username, - info)) + if (_dbus_hash_table_insert_string (db->users_by_name, + info->username, + info)) + { + _dbus_user_info_ref (info); + } + else { _dbus_hash_table_remove_uintptr (db->users, info->uid); dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + _dbus_user_info_unref (info); return NULL; } - + + _dbus_user_info_unref (info); + + /* Return a borrowed pointer to the DBusUserInfo owned by the + * hash tables */ return info; } } @@ -568,24 +605,24 @@ _dbus_user_database_new (void) db->refcount = 1; db->users = _dbus_hash_table_new (DBUS_HASH_UINTPTR, - NULL, (DBusFreeFunction) _dbus_user_info_free_allocated); + NULL, (DBusFreeFunction) _dbus_user_info_unref); if (db->users == NULL) goto failed; db->groups = _dbus_hash_table_new (DBUS_HASH_UINTPTR, - NULL, (DBusFreeFunction) _dbus_group_info_free_allocated); + NULL, (DBusFreeFunction) _dbus_group_info_unref); if (db->groups == NULL) goto failed; db->users_by_name = _dbus_hash_table_new (DBUS_HASH_STRING, - NULL, NULL); + NULL, (DBusFreeFunction) _dbus_user_info_unref); if (db->users_by_name == NULL) goto failed; db->groups_by_name = _dbus_hash_table_new (DBUS_HASH_STRING, - NULL, NULL); + NULL, (DBusFreeFunction) _dbus_group_info_unref); if (db->groups_by_name == NULL) goto failed; diff --git a/dbus/dbus-userdb.h b/dbus/dbus-userdb.h index 53fc90b5..b38e3d18 100644 --- a/dbus/dbus-userdb.h +++ b/dbus/dbus-userdb.h @@ -76,19 +76,19 @@ dbus_bool_t _dbus_user_database_get_groupname (DBusUserDatabase *db, DBusError *error); DBUS_PRIVATE_EXPORT -DBusUserInfo* _dbus_user_database_lookup (DBusUserDatabase *db, +const DBusUserInfo *_dbus_user_database_lookup (DBusUserDatabase *db, dbus_uid_t uid, const DBusString *username, DBusError *error); DBUS_PRIVATE_EXPORT -DBusGroupInfo* _dbus_user_database_lookup_group (DBusUserDatabase *db, - dbus_gid_t gid, - const DBusString *groupname, - DBusError *error); -DBUS_PRIVATE_EXPORT -void _dbus_user_info_free_allocated (DBusUserInfo *info); +const DBusGroupInfo* _dbus_user_database_lookup_group (DBusUserDatabase *db, + dbus_gid_t gid, + const DBusString *groupname, + DBusError *error); + +void _dbus_user_info_unref (DBusUserInfo *info); DBUS_PRIVATE_EXPORT -void _dbus_group_info_free_allocated (DBusGroupInfo *info); +void _dbus_group_info_unref (DBusGroupInfo *info); #endif /* DBUS_USERDB_INCLUDES_PRIVATE */ DBUS_PRIVATE_EXPORT diff --git a/doc/Makefile.in b/doc/Makefile.in index 08e84de7..dd120616 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -774,8 +774,8 @@ distclean-generic: maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -@DBUS_DOXYGEN_DOCS_ENABLED_FALSE@uninstall-local: @DBUS_DOXYGEN_DOCS_ENABLED_FALSE@install-data-local: +@DBUS_DOXYGEN_DOCS_ENABLED_FALSE@uninstall-local: clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am diff --git a/test/Makefile.in b/test/Makefile.in index 9be908e9..8516b4af 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # aminclude_static.am generated automatically by Autoconf -# from AX_AM_MACROS_STATIC on Tue Jun 2 13:56:47 BST 2020 +# from AX_AM_MACROS_STATIC on Thu Jul 2 11:10:39 BST 2020