17add50d820938123b7f163bbc5b528623065b7b1Colin Cross/* 27add50d820938123b7f163bbc5b528623065b7b1Colin Cross * Copyright (C) 2016 The Android Open Source Project 37add50d820938123b7f163bbc5b528623065b7b1Colin Cross * 47add50d820938123b7f163bbc5b528623065b7b1Colin Cross * Licensed under the Apache License, Version 2.0 (the "License"); 57add50d820938123b7f163bbc5b528623065b7b1Colin Cross * you may not use this file except in compliance with the License. 67add50d820938123b7f163bbc5b528623065b7b1Colin Cross * You may obtain a copy of the License at 77add50d820938123b7f163bbc5b528623065b7b1Colin Cross * 87add50d820938123b7f163bbc5b528623065b7b1Colin Cross * http://www.apache.org/licenses/LICENSE-2.0 97add50d820938123b7f163bbc5b528623065b7b1Colin Cross * 107add50d820938123b7f163bbc5b528623065b7b1Colin Cross * Unless required by applicable law or agreed to in writing, software 117add50d820938123b7f163bbc5b528623065b7b1Colin Cross * distributed under the License is distributed on an "AS IS" BASIS, 127add50d820938123b7f163bbc5b528623065b7b1Colin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137add50d820938123b7f163bbc5b528623065b7b1Colin Cross * See the License for the specific language governing permissions and 147add50d820938123b7f163bbc5b528623065b7b1Colin Cross * limitations under the License. 157add50d820938123b7f163bbc5b528623065b7b1Colin Cross */ 167add50d820938123b7f163bbc5b528623065b7b1Colin Cross 177add50d820938123b7f163bbc5b528623065b7b1Colin Cross#include <errno.h> 187add50d820938123b7f163bbc5b528623065b7b1Colin Cross#include <string.h> 197add50d820938123b7f163bbc5b528623065b7b1Colin Cross 207add50d820938123b7f163bbc5b528623065b7b1Colin Cross#include "LeakPipe.h" 217add50d820938123b7f163bbc5b528623065b7b1Colin Cross 227add50d820938123b7f163bbc5b528623065b7b1Colin Cross#include "log.h" 237add50d820938123b7f163bbc5b528623065b7b1Colin Cross 247add50d820938123b7f163bbc5b528623065b7b1Colin Crossbool LeakPipe::SendFd(int sock, int fd) { 257add50d820938123b7f163bbc5b528623065b7b1Colin Cross struct msghdr hdr{}; 267add50d820938123b7f163bbc5b528623065b7b1Colin Cross struct iovec iov{}; 277add50d820938123b7f163bbc5b528623065b7b1Colin Cross unsigned int data = 0xfdfdfdfd; 287add50d820938123b7f163bbc5b528623065b7b1Colin Cross alignas(struct cmsghdr) char cmsgbuf[CMSG_SPACE(sizeof(int))]; 297add50d820938123b7f163bbc5b528623065b7b1Colin Cross 307add50d820938123b7f163bbc5b528623065b7b1Colin Cross hdr.msg_iov = &iov; 317add50d820938123b7f163bbc5b528623065b7b1Colin Cross hdr.msg_iovlen = 1; 327add50d820938123b7f163bbc5b528623065b7b1Colin Cross iov.iov_base = &data; 337add50d820938123b7f163bbc5b528623065b7b1Colin Cross iov.iov_len = sizeof(data); 347add50d820938123b7f163bbc5b528623065b7b1Colin Cross 357add50d820938123b7f163bbc5b528623065b7b1Colin Cross hdr.msg_control = cmsgbuf; 367add50d820938123b7f163bbc5b528623065b7b1Colin Cross hdr.msg_controllen = CMSG_LEN(sizeof(int)); 377add50d820938123b7f163bbc5b528623065b7b1Colin Cross 387add50d820938123b7f163bbc5b528623065b7b1Colin Cross struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr); 397add50d820938123b7f163bbc5b528623065b7b1Colin Cross cmsg->cmsg_len = CMSG_LEN(sizeof(int)); 407add50d820938123b7f163bbc5b528623065b7b1Colin Cross cmsg->cmsg_level = SOL_SOCKET; 417add50d820938123b7f163bbc5b528623065b7b1Colin Cross cmsg->cmsg_type = SCM_RIGHTS; 427add50d820938123b7f163bbc5b528623065b7b1Colin Cross 437add50d820938123b7f163bbc5b528623065b7b1Colin Cross *(int*)CMSG_DATA(cmsg) = fd; 447add50d820938123b7f163bbc5b528623065b7b1Colin Cross 457add50d820938123b7f163bbc5b528623065b7b1Colin Cross int ret = sendmsg(sock, &hdr, 0); 467add50d820938123b7f163bbc5b528623065b7b1Colin Cross if (ret < 0) { 477add50d820938123b7f163bbc5b528623065b7b1Colin Cross ALOGE("failed to send fd: %s", strerror(errno)); 487add50d820938123b7f163bbc5b528623065b7b1Colin Cross return false; 497add50d820938123b7f163bbc5b528623065b7b1Colin Cross } 507add50d820938123b7f163bbc5b528623065b7b1Colin Cross if (ret == 0) { 517add50d820938123b7f163bbc5b528623065b7b1Colin Cross ALOGE("eof when sending fd"); 527add50d820938123b7f163bbc5b528623065b7b1Colin Cross return false; 537add50d820938123b7f163bbc5b528623065b7b1Colin Cross } 547add50d820938123b7f163bbc5b528623065b7b1Colin Cross 557add50d820938123b7f163bbc5b528623065b7b1Colin Cross return true; 567add50d820938123b7f163bbc5b528623065b7b1Colin Cross} 577add50d820938123b7f163bbc5b528623065b7b1Colin Cross 587add50d820938123b7f163bbc5b528623065b7b1Colin Crossint LeakPipe::ReceiveFd(int sock) { 597add50d820938123b7f163bbc5b528623065b7b1Colin Cross struct msghdr hdr{}; 607add50d820938123b7f163bbc5b528623065b7b1Colin Cross struct iovec iov{}; 617add50d820938123b7f163bbc5b528623065b7b1Colin Cross unsigned int data; 627add50d820938123b7f163bbc5b528623065b7b1Colin Cross alignas(struct cmsghdr) char cmsgbuf[CMSG_SPACE(sizeof(int))]; 637add50d820938123b7f163bbc5b528623065b7b1Colin Cross 647add50d820938123b7f163bbc5b528623065b7b1Colin Cross hdr.msg_iov = &iov; 657add50d820938123b7f163bbc5b528623065b7b1Colin Cross hdr.msg_iovlen = 1; 667add50d820938123b7f163bbc5b528623065b7b1Colin Cross iov.iov_base = &data; 677add50d820938123b7f163bbc5b528623065b7b1Colin Cross iov.iov_len = sizeof(data); 687add50d820938123b7f163bbc5b528623065b7b1Colin Cross 697add50d820938123b7f163bbc5b528623065b7b1Colin Cross hdr.msg_control = cmsgbuf; 707add50d820938123b7f163bbc5b528623065b7b1Colin Cross hdr.msg_controllen = CMSG_LEN(sizeof(int)); 717add50d820938123b7f163bbc5b528623065b7b1Colin Cross 727add50d820938123b7f163bbc5b528623065b7b1Colin Cross int ret = recvmsg(sock, &hdr, 0); 737add50d820938123b7f163bbc5b528623065b7b1Colin Cross if (ret < 0) { 747add50d820938123b7f163bbc5b528623065b7b1Colin Cross ALOGE("failed to receive fd: %s", strerror(errno)); 757add50d820938123b7f163bbc5b528623065b7b1Colin Cross return -1; 767add50d820938123b7f163bbc5b528623065b7b1Colin Cross } 777add50d820938123b7f163bbc5b528623065b7b1Colin Cross if (ret == 0) { 787add50d820938123b7f163bbc5b528623065b7b1Colin Cross ALOGE("eof when receiving fd"); 797add50d820938123b7f163bbc5b528623065b7b1Colin Cross return -1; 807add50d820938123b7f163bbc5b528623065b7b1Colin Cross } 817add50d820938123b7f163bbc5b528623065b7b1Colin Cross 827add50d820938123b7f163bbc5b528623065b7b1Colin Cross struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr); 837add50d820938123b7f163bbc5b528623065b7b1Colin Cross if (cmsg == NULL || cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { 847add50d820938123b7f163bbc5b528623065b7b1Colin Cross ALOGE("missing fd while receiving fd"); 857add50d820938123b7f163bbc5b528623065b7b1Colin Cross return -1; 867add50d820938123b7f163bbc5b528623065b7b1Colin Cross } 877add50d820938123b7f163bbc5b528623065b7b1Colin Cross 887add50d820938123b7f163bbc5b528623065b7b1Colin Cross return *(int*)CMSG_DATA(cmsg); 897add50d820938123b7f163bbc5b528623065b7b1Colin Cross} 90