about summary refs log tree commit diff
path: root/frida_mode/src/seccomp/seccomp_socket.c
blob: fbedbc75c88614e658b9820c23e6329c66705f50 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#if defined(__linux__) && !defined(__ANDROID__)

  #include <stdio.h>
  #include <string.h>
  #include <sys/socket.h>
  #include <unistd.h>

  #include "seccomp.h"
  #include "util.h"

union cmsg {

  char           buf[CMSG_SPACE(sizeof(int))];
  struct cmsghdr hdr;

};

void seccomp_socket_create(int *sock) {

  int tmp_sock[2] = {-1, -1};
  if (socketpair(AF_UNIX, SOCK_STREAM, 0, tmp_sock) < 0) {

    FFATAL("socketpair");

  }

  if (dup2(tmp_sock[STDIN_FILENO], SECCOMP_SOCKET_RECV_FD) < 0) {

    FFATAL("seccomp_socket_create - dup2 (1)");

  }

  if (dup2(tmp_sock[STDOUT_FILENO], SECCOMP_SOCKET_SEND_FD) < 0) {

    FFATAL("seccomp_socket_create - dup2 (1)");

  }

  if (close(tmp_sock[STDIN_FILENO]) < 0) {

    FFATAL("seccomp_socket_create - close (1)");

  }

  if (close(tmp_sock[STDOUT_FILENO]) < 0) {

    FFATAL("seccomp_socket_create - close (2)");

  }

  sock[STDIN_FILENO] = SECCOMP_SOCKET_RECV_FD;
  sock[STDOUT_FILENO] = SECCOMP_SOCKET_SEND_FD;

}

void seccomp_socket_send(int sockfd, int fd) {

  int          data = 12345;
  struct iovec iov = {.iov_base = &data, .iov_len = sizeof(data)};
  union cmsg   control_msg = {.hdr = {

                                  .cmsg_len = CMSG_LEN(sizeof(int)),
                                  .cmsg_level = SOL_SOCKET,
                                  .cmsg_type = SCM_RIGHTS,

                            }};

  struct msghdr message = {.msg_control = control_msg.buf,
                           .msg_controllen = sizeof(control_msg.buf),
                           .msg_flags = 0,
                           .msg_iov = &iov,
                           .msg_iovlen = 1,
                           .msg_name = NULL,
                           .msg_namelen = 0};

  memcpy(CMSG_DATA(&control_msg.hdr), &fd, sizeof(int));

  if (sendmsg(sockfd, &message, 0) == -1) { FFATAL("sendmsg"); }

}

int seccomp_socket_recv(int sockfd) {

  int           data;
  struct iovec  iov = {.iov_base = &data, .iov_len = sizeof(data)};
  union cmsg    control_msg = {0};
  struct msghdr message = {.msg_control = control_msg.buf,
                           .msg_controllen = sizeof(control_msg.buf),
                           .msg_flags = 0,
                           .msg_iov = &iov,
                           .msg_iovlen = 1,
                           .msg_name = NULL,
                           .msg_namelen = 0};

  int fd;

  if (recvmsg(sockfd, &message, 0) < 0) { FFATAL("recvmsg"); }

  if (control_msg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) {

    FFATAL("control_msg.hdr.cmsg_len");

  }

  if (control_msg.hdr.cmsg_level != SOL_SOCKET) {

    FFATAL("control_msg.hdr.cmsg_level");

  }

  if (control_msg.hdr.cmsg_type != SCM_RIGHTS) {

    FFATAL("control_msg.hdr.cmsg_type");

  }

  memcpy(&fd, CMSG_DATA(&control_msg.hdr), sizeof(int));

  return fd;

}

#endif