From: Simon McVittie Date: Fri, 12 Jan 2018 14:22:23 +0000 (+0000) Subject: _dbus_credentials_add_from_user: Add a fast-path for numeric strings X-Git-Tag: dbus-1.13.0~25 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5634b2fec2b54212c1df15a14cb4ec64b59cc100;p=thirdparty%2Fdbus.git _dbus_credentials_add_from_user: Add a fast-path for numeric strings The very common case for this function is that during AUTH EXTERNAL, it receives a Unix uid encoded as an ASCII decimal integer. There is no need to look up such uids in the system's user database (/etc/password or NSS) when the only information we are going to use from the DBusUserInfo struct is the uid anyway. This avoids taking the lock and performing a potentially time-consuming NSS lookup. This changes behaviour in one corner case: if a privileged process has used one of the set*uid family of functions to set its effective uid to a numeric uid that does not exist in the system's user database, we would previously fail. Now, we succeed anyway: it is true to say in the DBusCredentials that the process has uid 12345, even if uid 12345 does not correspond to any named user. Signed-off-by: Simon McVittie Reviewed-by: Philip Withnall Bug: https://bugs.freedesktop.org/show_bug.cgi?id=104588 --- diff --git a/dbus/dbus-userdb.c b/dbus/dbus-userdb.c index 4c42b7dd7..f79884c77 100644 --- a/dbus/dbus-userdb.c +++ b/dbus/dbus-userdb.c @@ -522,6 +522,18 @@ _dbus_credentials_add_from_user (DBusCredentials *credentials, { DBusUserDatabase *db; const DBusUserInfo *info; + unsigned long uid = DBUS_UID_UNSET; + + /* Fast-path for the common case: if the "username" is all-numeric, + * then it's a Unix uid. This is true regardless of whether that uid + * exists in NSS or /etc/passwd or equivalent. */ + if (_dbus_is_a_number (username, &uid)) + { + _DBUS_STATIC_ASSERT (sizeof (uid) == sizeof (dbus_uid_t)); + + _dbus_credentials_add_unix_uid (credentials, uid); + return TRUE; + } /* FIXME: this can't distinguish ENOMEM from other errors */ if (!_dbus_user_database_lock_system ())