From: Luca Boccassi Date: Mon, 20 Mar 2023 02:00:51 +0000 (+0000) Subject: DBusCredentials: add support for PID FDs via SO_PEERPIDFD X-Git-Tag: dbus-1.15.8~26^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=80d523dcc82268096d3a50643650413ef749e94b;p=thirdparty%2Fdbus.git DBusCredentials: add support for PID FDs via SO_PEERPIDFD The new socket option SO_PEERPIDFD allows to pin the process on the other side of the socket by file descriptor, which closes a race condition where a PID can be reused before we can pin it manually. Available since Linux v6.5. When storing credentials, pin the process by FD from the PID. When querying the PID, if the PID FD is available, resolve it from there first if possible. Ensure the DBusCredentials object only returns the PID FD if it was obtained by this call, so that we know for sure we can rely on it being safe against PID reuse attacks. Signed-off-by: Luca Boccassi --- diff --git a/cmake/ConfigureChecks.cmake b/cmake/ConfigureChecks.cmake index 4e0c9ce6c..737913bac 100644 --- a/cmake/ConfigureChecks.cmake +++ b/cmake/ConfigureChecks.cmake @@ -42,6 +42,7 @@ set(HAVE_BACKTRACE ${Backtrace_FOUND}) check_symbol_exists(LOG_PERROR "syslog.h" HAVE_DECL_LOG_PERROR) check_symbol_exists(MSG_NOSIGNAL "sys/socket.h" HAVE_DECL_MSG_NOSIGNAL) check_symbol_exists(SCM_RIGHTS "sys/types.h;sys/socket.h;sys/un.h" HAVE_UNIX_FD_PASSING) +check_symbol_exists(SYS_pidfd_open "sys/syscall.h" HAVE_DECL_SYS_PIDFD_OPEN) # dbus-sysdeps-unix.c check_symbol_exists(accept4 "sys/socket.h" HAVE_ACCEPT4) check_symbol_exists(clearenv "stdlib.h" HAVE_CLEARENV) # dbus-sysdeps.c check_symbol_exists(close_range "unistd.h" HAVE_CLOSE_RANGE) # dbus-sysdeps-unix.c diff --git a/cmake/config.h.cmake b/cmake/config.h.cmake index a4811b540..e16d2247d 100644 --- a/cmake/config.h.cmake +++ b/cmake/config.h.cmake @@ -262,5 +262,6 @@ #cmakedefine01 HAVE_DECL_ENVIRON #cmakedefine01 HAVE_DECL_LOG_PERROR #cmakedefine01 HAVE_DECL_MSG_NOSIGNAL +#cmakedefine01 HAVE_DECL_SYS_PIDFD_OPEN #endif // _DBUS_CONFIG_H diff --git a/configure.ac b/configure.ac index f6ce9e6cb..b1809e755 100644 --- a/configure.ac +++ b/configure.ac @@ -1029,6 +1029,8 @@ fi AC_CHECK_HEADERS(sys/vfs.h, [AC_CHECK_FUNCS(fstatfs)]) AC_CHECK_HEADERS([linux/magic.h]) +AC_CHECK_DECLS([SYS_pidfd_open], [], [], [[ #include ]]) + #### Set up final flags LIBDBUS_LIBS="$THREAD_LIBS $NETWORK_libs $SYSTEMD_LIBS" AC_SUBST([LIBDBUS_LIBS]) diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c index bcb612a8c..09942f801 100644 --- a/dbus/dbus-auth.c +++ b/dbus/dbus-auth.c @@ -803,8 +803,12 @@ sha1_handle_second_client_response (DBusAuth *auth, auth->desired_identity)) goto out_3; - /* Copy process ID from the socket credentials if it's there + /* Copy process ID (and PID FD) from the socket credentials if it's there */ + if (!_dbus_credentials_add_credential (auth->authorized_identity, + DBUS_CREDENTIAL_UNIX_PROCESS_FD, + auth->credentials)) + goto out_3; if (!_dbus_credentials_add_credential (auth->authorized_identity, DBUS_CREDENTIAL_UNIX_PROCESS_ID, auth->credentials)) @@ -1187,6 +1191,11 @@ handle_server_data_external_mech (DBusAuth *auth, /* also copy misc process info from the socket credentials */ + if (!_dbus_credentials_add_credential (auth->authorized_identity, + DBUS_CREDENTIAL_UNIX_PROCESS_FD, + auth->credentials)) + return FALSE; + if (!_dbus_credentials_add_credential (auth->authorized_identity, DBUS_CREDENTIAL_UNIX_PROCESS_ID, auth->credentials)) @@ -1304,8 +1313,13 @@ handle_server_data_anonymous_mech (DBusAuth *auth, /* We want to be anonymous (clear in case some other protocol got midway through I guess) */ _dbus_credentials_clear (auth->desired_identity); - /* Copy process ID from the socket credentials + /* Copy process ID (and PID FD) from the socket credentials */ + if (!_dbus_credentials_add_credential (auth->authorized_identity, + DBUS_CREDENTIAL_UNIX_PROCESS_FD, + auth->credentials)) + return FALSE; + if (!_dbus_credentials_add_credential (auth->authorized_identity, DBUS_CREDENTIAL_UNIX_PROCESS_ID, auth->credentials)) diff --git a/dbus/dbus-credentials.c b/dbus/dbus-credentials.c index d932865e3..44cd40bfc 100644 --- a/dbus/dbus-credentials.c +++ b/dbus/dbus-credentials.c @@ -25,8 +25,17 @@ #include #include #include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_SYSCALL_H +#include +#endif #include "dbus-credentials.h" #include "dbus-internals.h" +#ifdef DBUS_UNIX +#include "dbus-sysdeps-unix.h" +#endif /** * @defgroup DBusCredentials Credentials provable through authentication @@ -54,6 +63,7 @@ struct DBusCredentials { dbus_gid_t *unix_gids; size_t n_unix_gids; dbus_pid_t pid; + int pid_fd; char *windows_sid; char *linux_security_label; void *adt_audit_data; @@ -86,6 +96,7 @@ _dbus_credentials_new (void) creds->unix_gids = NULL; creds->n_unix_gids = 0; creds->pid = DBUS_PID_UNSET; + creds->pid_fd = -1; creds->windows_sid = NULL; creds->linux_security_label = NULL; creds->adt_audit_data = NULL; @@ -145,12 +156,22 @@ _dbus_credentials_unref (DBusCredentials *credentials) dbus_free (credentials->windows_sid); dbus_free (credentials->linux_security_label); dbus_free (credentials->adt_audit_data); +#ifdef DBUS_UNIX + if (credentials->pid_fd >= 0) + { + close (credentials->pid_fd); + credentials->pid_fd = -1; + } +#endif dbus_free (credentials); } } /** - * Add a UNIX process ID to the credentials. + * Add a UNIX process ID to the credentials. If the + * process ID FD is set, it will always take + * precendence when querying the PID of this + * credential. * * @param credentials the object * @param pid the process ID @@ -164,6 +185,30 @@ _dbus_credentials_add_pid (DBusCredentials *credentials, return TRUE; } +/** + * Add a UNIX process ID FD to the credentials. The + * FD is now owned by the credentials object. + * + * @param credentials the object + * @param pid_fd the process ID FD + * @returns #FALSE if no memory + */ +#ifndef DBUS_UNIX +_DBUS_GNUC_NORETURN +#endif +void +_dbus_credentials_take_pid_fd (DBusCredentials *credentials, + int pid_fd) +{ +#ifdef DBUS_UNIX + if (credentials->pid_fd >= 0) + close (credentials->pid_fd); + credentials->pid_fd = pid_fd; +#else + _dbus_assert_not_reached ("pidfd never set on non-Unix"); +#endif +} + /** * Add a UNIX user ID to the credentials. * @@ -323,7 +368,10 @@ _dbus_credentials_include (DBusCredentials *credentials, switch (type) { case DBUS_CREDENTIAL_UNIX_PROCESS_ID: - return credentials->pid != DBUS_PID_UNSET; + return credentials->pid != DBUS_PID_UNSET || + credentials->pid_fd >= 0; + case DBUS_CREDENTIAL_UNIX_PROCESS_FD: + return credentials->pid_fd >= 0; case DBUS_CREDENTIAL_UNIX_USER_ID: return credentials->unix_uid != DBUS_UID_UNSET; case DBUS_CREDENTIAL_UNIX_GROUP_IDS: @@ -343,6 +391,8 @@ _dbus_credentials_include (DBusCredentials *credentials, /** * Gets the UNIX process ID in the credentials, or #DBUS_PID_UNSET if * the credentials object doesn't contain a process ID. + * If the PID FD is set, it will first try to resolve from it, and + * only return the stored PID if that fails. * * @param credentials the object * @returns UNIX process ID @@ -350,9 +400,35 @@ _dbus_credentials_include (DBusCredentials *credentials, dbus_pid_t _dbus_credentials_get_pid (DBusCredentials *credentials) { +#ifdef DBUS_UNIX + dbus_pid_t pid; + + if (credentials->pid_fd >= 0) + { + pid = _dbus_resolve_pid_fd (credentials->pid_fd); + if (pid > 0) + return pid; + } +#endif + return credentials->pid; } +/** + * Gets the UNIX process ID FD in the credentials as obtained by 'safe' + * means (e.g.: Linux's SO_PEERPIDFD), or -1 if the credentials object + * doesn't contain a process ID FD. The file FD is owned by the credentials + * object and must not be closed by the caller. + * + * @param credentials the object + * @returns UNIX process ID FD + */ +int +_dbus_credentials_get_pid_fd (DBusCredentials *credentials) +{ + return credentials->pid_fd; +} + /** * Gets the UNIX user ID in the credentials, or #DBUS_UID_UNSET if * the credentials object doesn't contain a user ID. @@ -463,6 +539,7 @@ _dbus_credentials_are_empty (DBusCredentials *credentials) { return credentials->pid == DBUS_PID_UNSET && + credentials->pid_fd == -1 && credentials->unix_uid == DBUS_UID_UNSET && credentials->unix_gids == NULL && credentials->n_unix_gids == 0 && @@ -498,6 +575,9 @@ _dbus_credentials_add_credentials (DBusCredentials *credentials, DBusCredentials *other_credentials) { return + _dbus_credentials_add_credential (credentials, + DBUS_CREDENTIAL_UNIX_PROCESS_FD, + other_credentials) && _dbus_credentials_add_credential (credentials, DBUS_CREDENTIAL_UNIX_PROCESS_ID, other_credentials) && @@ -582,6 +662,19 @@ _dbus_credentials_add_credential (DBusCredentials *credentials, if (!_dbus_credentials_add_adt_audit_data (credentials, other_credentials->adt_audit_data, other_credentials->adt_audit_data_size)) return FALSE; } + /* _dbus_dup() is only available on UNIX platforms. */ +#ifdef DBUS_UNIX + else if (which == DBUS_CREDENTIAL_UNIX_PROCESS_FD && + other_credentials->pid_fd >= 0) + { + int pid_fd = _dbus_dup (other_credentials->pid_fd, NULL); + + if (pid_fd < 0) + return FALSE; + + _dbus_credentials_take_pid_fd (credentials, pid_fd); + } +#endif return TRUE; } @@ -595,6 +688,13 @@ void _dbus_credentials_clear (DBusCredentials *credentials) { credentials->pid = DBUS_PID_UNSET; +#ifdef DBUS_UNIX + if (credentials->pid_fd >= 0) + { + close (credentials->pid_fd); + credentials->pid_fd = -1; + } +#endif credentials->unix_uid = DBUS_UID_UNSET; dbus_free (credentials->unix_gids); credentials->unix_gids = NULL; @@ -677,9 +777,12 @@ _dbus_credentials_to_string_append (DBusCredentials *credentials, goto oom; join = TRUE; } - if (credentials->pid != DBUS_PID_UNSET) + if (credentials->pid != DBUS_PID_UNSET || credentials->pid_fd >= 0) { - if (!_dbus_string_append_printf (string, "%spid=" DBUS_PID_FORMAT, join ? " " : "", credentials->pid)) + if (!_dbus_string_append_printf (string, + "%spid=" DBUS_PID_FORMAT, + join ? " " : "", + _dbus_credentials_get_pid (credentials))) goto oom; join = TRUE; } @@ -715,6 +818,13 @@ _dbus_credentials_to_string_append (DBusCredentials *credentials, join = TRUE; } + if (credentials->pid_fd >= 0) + { + if (!_dbus_string_append_printf (string, "%spidfd=%d", join ? " " : "", credentials->pid_fd)) + goto oom; + join = TRUE; + } + return TRUE; oom: return FALSE; diff --git a/dbus/dbus-credentials.h b/dbus/dbus-credentials.h index 6da0d1ae8..407d5cb52 100644 --- a/dbus/dbus-credentials.h +++ b/dbus/dbus-credentials.h @@ -38,7 +38,8 @@ typedef enum { DBUS_CREDENTIAL_UNIX_GROUP_IDS, DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID, DBUS_CREDENTIAL_LINUX_SECURITY_LABEL, - DBUS_CREDENTIAL_WINDOWS_SID + DBUS_CREDENTIAL_WINDOWS_SID, + DBUS_CREDENTIAL_UNIX_PROCESS_FD, } DBusCredentialType; DBUS_PRIVATE_EXPORT @@ -53,6 +54,9 @@ DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_credentials_add_pid (DBusCredentials *credentials, dbus_pid_t pid); DBUS_PRIVATE_EXPORT +void _dbus_credentials_take_pid_fd (DBusCredentials *credentials, + int pid_fd); +DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_credentials_add_unix_uid (DBusCredentials *credentials, dbus_uid_t uid); DBUS_PRIVATE_EXPORT @@ -73,6 +77,8 @@ dbus_bool_t _dbus_credentials_include (DBusCredentials DBUS_PRIVATE_EXPORT dbus_pid_t _dbus_credentials_get_pid (DBusCredentials *credentials); DBUS_PRIVATE_EXPORT +int _dbus_credentials_get_pid_fd (DBusCredentials *credentials); +DBUS_PRIVATE_EXPORT dbus_uid_t _dbus_credentials_get_unix_uid (DBusCredentials *credentials); DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_credentials_get_unix_gids (DBusCredentials *credentials, diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index 6962b0771..c66096e07 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -2217,6 +2217,7 @@ _dbus_read_credentials_socket (DBusSocket client_fd, dbus_gid_t primary_gid_read; dbus_pid_t pid_read; int bytes_read; + int pid_fd_read; #ifdef HAVE_CMSGCRED union { @@ -2236,6 +2237,7 @@ _dbus_read_credentials_socket (DBusSocket client_fd, uid_read = DBUS_UID_UNSET; primary_gid_read = DBUS_GID_UNSET; pid_read = DBUS_PID_UNSET; + pid_fd_read = -1; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -2328,6 +2330,24 @@ _dbus_read_credentials_socket (DBusSocket client_fd, primary_gid_read = cr.gid; #endif } + +#ifdef SO_PEERPIDFD + /* If we have SO_PEERCRED we might also have SO_PEERPIDFD, which + * allows to pin the process ID, and is available on Linux since v6.5. */ + cr_len = sizeof (int); + + if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERPIDFD, &pid_fd_read, &cr_len) != 0) + { + _dbus_verbose ("Failed to getsockopt(SO_PEERPIDFD): %s\n", + _dbus_strerror (errno)); + } + else if (cr_len != sizeof (int)) + { + _dbus_verbose ("Failed to getsockopt(SO_PEERPIDFD), returned %d bytes, expected %d\n", + cr_len, (int) sizeof (int)); + } +#endif + #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID) /* Another variant of the above - used on NetBSD */ @@ -2483,6 +2503,11 @@ _dbus_read_credentials_socket (DBusSocket client_fd, pid_read, uid_read); + /* Assign this first, so we don't have to close it manually in case one of + * the next steps fails. */ + if (pid_fd_read >= 0) + _dbus_credentials_take_pid_fd (credentials, pid_fd_read); + if (pid_read != DBUS_PID_UNSET) { if (!_dbus_credentials_add_pid (credentials, pid_read)) @@ -2960,6 +2985,8 @@ _dbus_user_info_fill_uid (DBusUserInfo *info, dbus_bool_t _dbus_credentials_add_from_current_process (DBusCredentials *credentials) { + dbus_pid_t pid = _dbus_getpid (); + /* The POSIX spec certainly doesn't promise this, but * we need these assertions to fail as soon as we're wrong about * it so we can do the porting fixups @@ -2968,7 +2995,14 @@ _dbus_credentials_add_from_current_process (DBusCredentials *credentials) _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t)); _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t)); - if (!_dbus_credentials_add_pid(credentials, _dbus_getpid())) +#if HAVE_DECL_SYS_PIDFD_OPEN + /* Normally this syscall would have a race condition, but we can trust + * that our own process isn't going to exit, so the pid won't get reused. */ + int pid_fd = (int) syscall (SYS_pidfd_open, pid, 0); + if (pid_fd >= 0) + _dbus_credentials_take_pid_fd (credentials, pid_fd); +#endif + if (!_dbus_credentials_add_pid (credentials, pid)) return FALSE; if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid())) return FALSE; @@ -2976,6 +3010,79 @@ _dbus_credentials_add_from_current_process (DBusCredentials *credentials) return TRUE; } +/** + * Resolve the PID from the PID FD, if any. This allows us to avoid + * PID reuse attacks. Returns DBUS_PID_UNSET if the PID could not be resolved. + * Note that this requires being able to read /proc/self/fdinfo/, + * which is created as 600 and owned by the original UID that the + * process started as. So it cannot work when the start as root and + * drop privileges mechanism is in use (the systemd unit no longer + * does this, but third-party init-scripts might). + * + * @param pid_fd the PID FD + * @returns the resolved PID if found, DBUS_PID_UNSET otherwise + */ +dbus_pid_t +_dbus_resolve_pid_fd (int pid_fd) +{ +#ifdef __linux__ + DBusError error = DBUS_ERROR_INIT; + DBusString content = _DBUS_STRING_INIT_INVALID; + DBusString filename = _DBUS_STRING_INIT_INVALID; + dbus_pid_t result = DBUS_PID_UNSET; + int pid_index; + + if (pid_fd < 0) + goto out; + + if (!_dbus_string_init (&content)) + goto out; + + if (!_dbus_string_init (&filename)) + goto out; + + if (!_dbus_string_append_printf (&filename, "/proc/self/fdinfo/%d", pid_fd)) + goto out; + + if (!_dbus_file_get_contents (&content, &filename, &error)) + { + _dbus_verbose ("Cannot read '/proc/self/fdinfo/%d', unable to resolve PID, %s: %s\n", + pid_fd, error.name, error.message); + goto out; + } + + /* Ensure we are not reading PPid, either it's the first line of the file or + * there's a newline before it. */ + if (!_dbus_string_find (&content, 0, "Pid:", &pid_index) || + (pid_index > 0 && _dbus_string_get_byte (&content, pid_index - 1) != '\n')) + { + _dbus_verbose ("Cannot find 'Pid:' in '/proc/self/fdinfo/%d', unable to resolve PID\n", + pid_fd); + goto out; + } + + if (!_dbus_string_parse_uint (&content, pid_index + strlen ("Pid:"), &result, NULL)) + { + _dbus_verbose ("Cannot parse 'Pid:' from '/proc/self/fdinfo/%d', unable to resolve PID\n", + pid_fd); + goto out; + } + +out: + _dbus_string_free (&content); + _dbus_string_free (&filename); + dbus_error_free (&error); + + if (result <= 0) + return DBUS_PID_UNSET; + + return result; +#else + return DBUS_PID_UNSET; +#endif + +} + /** * Append to the string the identity we would like to have when we * authenticate, on UNIX this is the current process UID and on diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 36ababdb5..e97371790 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -311,6 +311,18 @@ dbus_bool_t _dbus_daemon_unpublish_session_bus_address (void); dbus_bool_t _dbus_socket_can_pass_unix_fd(DBusSocket fd); +/* PID FDs are Linux-specific. */ +#ifdef DBUS_WIN +static inline dbus_pid_t _dbus_resolve_pid_fd (int pid_fd) +{ + return DBUS_PID_UNSET; +} + +#else +DBUS_PRIVATE_EXPORT +dbus_pid_t _dbus_resolve_pid_fd (int pid_fd); +#endif + /** Opaque type representing an atomically-modifiable integer * that can be used from multiple threads. */ diff --git a/meson.build b/meson.build index 5438b1843..9bfcb4a89 100644 --- a/meson.build +++ b/meson.build @@ -769,6 +769,14 @@ config.set('HAVE_FSTATFS', ) ) +config.set10('HAVE_DECL_SYS_PIDFD_OPEN', + cc.has_header_symbol( + 'sys/syscall.h', + 'SYS_pidfd_open', + args: compile_args_c, + ) +) + ############################################################################### # Project options diff --git a/test/internals/dbus-credentials-util.c b/test/internals/dbus-credentials-util.c index 06400925a..6fada3029 100644 --- a/test/internals/dbus-credentials-util.c +++ b/test/internals/dbus-credentials-util.c @@ -129,13 +129,15 @@ _dbus_credentials_test (const char *test_data_dir) DBusCredentials *creds; DBusCredentials *creds2; DBusString str; + DBusString str2; const dbus_gid_t *gids; size_t n; + dbus_pid_t pid = _dbus_getpid(); if (test_data_dir == NULL) return TRUE; - creds = make_credentials (12, 511, 1, SAMPLE_SID); + creds = make_credentials (12, pid, 1, SAMPLE_SID); if (creds == NULL) _dbus_test_fatal ("oom"); @@ -149,7 +151,7 @@ _dbus_credentials_test (const char *test_data_dir) _dbus_assert (_dbus_credentials_include (creds, DBUS_CREDENTIAL_WINDOWS_SID)); _dbus_assert (_dbus_credentials_get_unix_uid (creds) == 12); - _dbus_assert (_dbus_credentials_get_pid (creds) == 511); + _dbus_assert (_dbus_credentials_get_pid (creds) == pid); _dbus_assert (strcmp (_dbus_credentials_get_windows_sid (creds), SAMPLE_SID) == 0); _dbus_assert (_dbus_credentials_get_unix_gids (creds, &gids, &n)); _dbus_assert (n == 4); @@ -172,7 +174,7 @@ _dbus_credentials_test (const char *test_data_dir) _dbus_assert (_dbus_credentials_include (creds2, DBUS_CREDENTIAL_WINDOWS_SID)); _dbus_assert (_dbus_credentials_get_unix_uid (creds2) == 12); - _dbus_assert (_dbus_credentials_get_pid (creds2) == 511); + _dbus_assert (_dbus_credentials_get_pid (creds2) == pid); _dbus_assert (strcmp (_dbus_credentials_get_windows_sid (creds2), SAMPLE_SID) == 0); _dbus_assert (_dbus_credentials_get_unix_gids (creds2, &gids, &n)); _dbus_assert (n == 4); @@ -245,7 +247,7 @@ _dbus_credentials_test (const char *test_data_dir) _dbus_credentials_unref (creds2); /* Same user, but not a superset, if groups are different */ - creds2 = make_credentials (12, 511, 2, SAMPLE_SID); + creds2 = make_credentials (12, pid, 2, SAMPLE_SID); if (creds2 == NULL) _dbus_test_fatal ("oom"); @@ -255,7 +257,7 @@ _dbus_credentials_test (const char *test_data_dir) _dbus_credentials_unref (creds2); /* Groups being in the same order make no difference */ - creds2 = make_credentials (12, 511, 3, SAMPLE_SID); + creds2 = make_credentials (12, pid, 3, SAMPLE_SID); if (creds2 == NULL) _dbus_test_fatal ("oom"); @@ -282,7 +284,7 @@ _dbus_credentials_test (const char *test_data_dir) _dbus_credentials_unref (creds); /* Make some more realistic credentials blobs to test stringification */ - if (!_dbus_string_init (&str)) + if (!_dbus_string_init (&str) || !_dbus_string_init (&str2)) _dbus_test_fatal ("oom"); creds = make_credentials (12, DBUS_PID_UNSET, 0, NULL); @@ -298,7 +300,7 @@ _dbus_credentials_test (const char *test_data_dir) _dbus_credentials_unref (creds); - creds = make_credentials (12, 511, 1, NULL); + creds = make_credentials (12, pid, 1, NULL); if (creds == NULL) _dbus_test_fatal ("oom"); @@ -308,9 +310,11 @@ _dbus_credentials_test (const char *test_data_dir) if (!_dbus_credentials_to_string_append (creds, &str)) _dbus_test_fatal ("oom"); + if (!_dbus_string_append_printf(&str2, "uid=12 pid=" DBUS_PID_FORMAT " gid=42 gid=123 gid=1000 gid=5678", pid)) + _dbus_test_fatal ("oom"); + _dbus_test_diag ("Unix complete set: %s", _dbus_string_get_const_data (&str)); - _dbus_assert (strcmp (_dbus_string_get_const_data (&str), - "uid=12 pid=511 gid=42 gid=123 gid=1000 gid=5678") == 0); + _dbus_assert (strcmp (_dbus_string_get_const_data (&str), _dbus_string_get_const_data (&str2)) == 0); _dbus_credentials_unref (creds); @@ -330,23 +334,26 @@ _dbus_credentials_test (const char *test_data_dir) _dbus_credentials_unref (creds); - creds = make_credentials (DBUS_UID_UNSET, 511, 0, SAMPLE_SID); + creds = make_credentials (DBUS_UID_UNSET, pid, 0, SAMPLE_SID); if (creds == NULL) _dbus_test_fatal ("oom"); - if (!_dbus_string_set_length (&str, 0)) + if (!_dbus_string_set_length (&str, 0) || !_dbus_string_set_length (&str2, 0)) _dbus_test_fatal ("oom"); if (!_dbus_credentials_to_string_append (creds, &str)) _dbus_test_fatal ("oom"); + if (!_dbus_string_append_printf(&str2, "pid=" DBUS_PID_FORMAT " sid=" SAMPLE_SID, pid)) + _dbus_test_fatal ("oom"); + _dbus_test_diag ("Windows complete set: %s", _dbus_string_get_const_data (&str)); - _dbus_assert (strcmp (_dbus_string_get_const_data (&str), - "pid=511 sid=" SAMPLE_SID) == 0); + _dbus_assert (strcmp (_dbus_string_get_const_data (&str), _dbus_string_get_const_data (&str2)) == 0); _dbus_credentials_unref (creds); _dbus_string_free (&str); + _dbus_string_free (&str2); return TRUE; }