LeakPipe.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * Copyright (C) 2016 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <errno.h>
  17. #include <string.h>
  18. #include "LeakPipe.h"
  19. #include "log.h"
  20. namespace android {
  21. bool LeakPipe::SendFd(int sock, int fd) {
  22. struct msghdr hdr {};
  23. struct iovec iov {};
  24. unsigned int data = 0xfdfdfdfd;
  25. alignas(struct cmsghdr) char cmsgbuf[CMSG_SPACE(sizeof(int))];
  26. hdr.msg_iov = &iov;
  27. hdr.msg_iovlen = 1;
  28. iov.iov_base = &data;
  29. iov.iov_len = sizeof(data);
  30. hdr.msg_control = cmsgbuf;
  31. hdr.msg_controllen = CMSG_LEN(sizeof(int));
  32. struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr);
  33. cmsg->cmsg_len = CMSG_LEN(sizeof(int));
  34. cmsg->cmsg_level = SOL_SOCKET;
  35. cmsg->cmsg_type = SCM_RIGHTS;
  36. *(int*)CMSG_DATA(cmsg) = fd;
  37. int ret = sendmsg(sock, &hdr, 0);
  38. if (ret < 0) {
  39. MEM_ALOGE("failed to send fd: %s", strerror(errno));
  40. return false;
  41. }
  42. if (ret == 0) {
  43. MEM_ALOGE("eof when sending fd");
  44. return false;
  45. }
  46. return true;
  47. }
  48. int LeakPipe::ReceiveFd(int sock) {
  49. struct msghdr hdr {};
  50. struct iovec iov {};
  51. unsigned int data;
  52. alignas(struct cmsghdr) char cmsgbuf[CMSG_SPACE(sizeof(int))];
  53. hdr.msg_iov = &iov;
  54. hdr.msg_iovlen = 1;
  55. iov.iov_base = &data;
  56. iov.iov_len = sizeof(data);
  57. hdr.msg_control = cmsgbuf;
  58. hdr.msg_controllen = CMSG_LEN(sizeof(int));
  59. int ret = recvmsg(sock, &hdr, 0);
  60. if (ret < 0) {
  61. MEM_ALOGE("failed to receive fd: %s", strerror(errno));
  62. return -1;
  63. }
  64. if (ret == 0) {
  65. MEM_ALOGE("eof when receiving fd");
  66. return -1;
  67. }
  68. struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr);
  69. if (cmsg == NULL || cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
  70. MEM_ALOGE("missing fd while receiving fd");
  71. return -1;
  72. }
  73. return *(int*)CMSG_DATA(cmsg);
  74. }
  75. } // namespace android