summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2014-01-06 15:55:35 +0000
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2014-01-06 15:55:35 +0000
commita6bb4b7be996b935ddc6a20d2fa8e5bb2a9e36f5 (patch)
tree3e8bfed30260d0389dd706de576c59e852cb15c9
parent3ca8a53e336a1a829bae93c70fe617af6493201a (diff)
downloaddbus-a6bb4b7be996b935ddc6a20d2fa8e5bb2a9e36f5.tar.gz
_dbus_read_credentials_socket: look at all cmsg headers, not just the first
If there are no cmsg headers, don't fail: this fixes receiving credentials on TCP sockets under at least GNU/kFreeBSD, and probably FreeBSD too. If there's more than one cmsg header, ignore any that don't look like valid SCM_CREDS. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=69492 Tested-by: Svante Signell Reviewed-by: Chengwei Yang <chengwei.yang@intel.com> [added break, altered indentation in response to review -smcv] Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
-rw-r--r--dbus/dbus-sysdeps-unix.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index c12f294e..6fd1b764 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -1712,16 +1712,6 @@ _dbus_read_credentials_socket (int client_fd,
return FALSE;
}
-#if defined(HAVE_CMSGCRED)
- if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
- || cmsg.hdr.cmsg_type != SCM_CREDS)
- {
- dbus_set_error (error, DBUS_ERROR_FAILED,
- "Message from recvmsg() was not SCM_CREDS");
- return FALSE;
- }
-#endif
-
_dbus_verbose ("read credentials byte\n");
{
@@ -1762,10 +1752,22 @@ _dbus_read_credentials_socket (int client_fd,
* which makes it better than getpeereid().
*/
struct cmsgcred *cred;
+ struct cmsghdr *cmsgp;
- cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
- pid_read = cred->cmcred_pid;
- uid_read = cred->cmcred_euid;
+ for (cmsgp = CMSG_FIRSTHDR (&msg);
+ cmsgp != NULL;
+ cmsgp = CMSG_NXTHDR (&msg, cmsgp))
+ {
+ if (cmsgp->cmsg_type == SCM_CREDS &&
+ cmsgp->cmsg_level == SOL_SOCKET &&
+ cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
+ {
+ cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
+ pid_read = cred->cmcred_pid;
+ uid_read = cred->cmcred_euid;
+ break;
+ }
+ }
#elif defined(HAVE_GETPEERUCRED)
/* Supported in at least Solaris >= 10. It should probably be higher