--- a/sysdeps/mach/hurd/sendmsg.c +++ b/sysdeps/mach/hurd/sendmsg.c @@ -193,6 +193,49 @@ goto label; } + /* Special case: message->msg_controllen < sizeof (struct cmsghdr) */ + /* Special case: cmsg == NULL and zero credentials byte sent */ + else if (cmsg == NULL && (strncmp(data.ptr, "\0", 1) == 0)) + { + union { + struct cmsghdr cmh; + char control[CMSG_SPACE(sizeof(struct cmsgcred))]; + /* Space large enough to hold a cmsgcred structure */ + } control_un; + + struct msghdr msgh; + msgh.msg_name = NULL; + msgh.msg_namelen = 0; + msgh.msg_control = control_un.control; + msgh.msg_controllen = sizeof(control_un.control); + msgh.msg_flags = 0; + + struct cmsghdr *cmhp = CMSG_FIRSTHDR(&msgh); + cmhp->cmsg_level = SOL_SOCKET; + cmhp->cmsg_type = SCM_CREDS; + cmhp->cmsg_len = CMSG_LEN(sizeof(struct cmsgcred)); + + ucredp = (struct cmsgcred *) CMSG_DATA(cmhp); + /* FIXME: to remove pid: not checked in check_auth? */ + pid = __getpid(); + euids = __geteuid(); + auids = __getuid(); + egids = __getegid(); + agids = __getgid(); + euidslen = auidslen = egidslen = agidslen = 1; + + nports = 0; + control = control_un.control; + control_len = sizeof(control_un.control); + + err = check_auth(euids, euidslen, auids, auidslen, + egids, egidslen, agids, agidslen, + ucredp); + if (err) + return __hurd_fail (err); + goto label; + } + /* SCM_RIGHTS support: get the number of fds to send. */ cmsg = CMSG_FIRSTHDR (message); for (; cmsg; cmsg = CMSG_NXTHDR (message, cmsg))