diff --git a/sysdeps/managarm/generic/file.cpp b/sysdeps/managarm/generic/file.cpp index 8bf7e6cfb0..6b85507b19 100644 --- a/sysdeps/managarm/generic/file.cpp +++ b/sysdeps/managarm/generic/file.cpp @@ -869,20 +869,29 @@ int sys_msg_send(int sockfd, const struct msghdr *hdr, int flags, ssize_t *lengt for(auto cmsg = CMSG_FIRSTHDR(hdr); cmsg; cmsg = CMSG_NXTHDR(hdr, cmsg)) { __ensure(cmsg->cmsg_level == SOL_SOCKET); + __ensure(cmsg->cmsg_len >= sizeof(struct cmsghdr)); if(cmsg->cmsg_type == SCM_CREDENTIALS) { - mlibc::infoLogger() << "mlibc: SCM_CREDENTIALS requested but we don't handle that yet!" << frg::endlog; + req.set_has_cmsg_creds(true); + size_t size = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)); + __ensure(size == sizeof(struct ucred)); + struct ucred creds; + memcpy(&creds, CMSG_DATA(cmsg), sizeof(struct ucred)); + req.set_creds_pid(creds.pid); + req.set_creds_uid(creds.uid); + req.set_creds_gid(creds.gid); + } else if(cmsg->cmsg_type == SCM_RIGHTS) { + req.set_has_cmsg_rights(true); + size_t size = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)); + __ensure(!(size % sizeof(int))); + for(size_t off = 0; off < size; off += sizeof(int)) { + int fd; + memcpy(&fd, CMSG_DATA(cmsg) + off, sizeof(int)); + req.add_fds(fd); + } + } else { + mlibc::infoLogger() << "mlibc: sys_msg_send only supports SCM_RIGHTS or SCM_CREDENTIALS, got: " << cmsg->cmsg_type << "!" << frg::endlog; return EINVAL; } - __ensure(cmsg->cmsg_type == SCM_RIGHTS); - __ensure(cmsg->cmsg_len >= sizeof(struct cmsghdr)); - - size_t size = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)); - __ensure(!(size % sizeof(int))); - for(size_t off = 0; off < size; off += sizeof(int)) { - int fd; - memcpy(&fd, CMSG_DATA(cmsg) + off, sizeof(int)); - req.add_fds(fd); - } } auto [offer, send_head, send_tail, send_data, imbue_creds, send_addr, recv_resp] = exchangeMsgsSync(