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