check if uid changes across syscalls.
[trinity.git] / fds.c
blobcc1ca6d3041feeb7865b3df2c13999a696711002
1 #include <errno.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <sys/epoll.h>
7 #include <sys/eventfd.h>
9 #include "perf.h"
10 #include "random.h"
11 #include "shm.h"
12 #include "files.h"
13 #include "pids.h"
14 #include "net.h"
15 #include "log.h"
16 #include "sanitise.h"
17 #include "params.h"
19 /* Pipe FD related functions. */
20 static void open_pipes(void)
22 int pipes[2];
23 unsigned int i;
25 for (i = 0; i < MAX_PIPE_FDS; i+=2) {
26 if (pipe(pipes) < 0) {
27 perror("pipe fail.\n");
28 exit(EXIT_FAILURE);
30 shm->pipe_fds[i] = pipes[0];
31 shm->pipe_fds[i+1] = pipes[1];
33 output(2, "fd[%d] = pipe\n", shm->pipe_fds[i]);
34 output(2, "fd[%d] = pipe\n", shm->pipe_fds[i+1]);
38 static int rand_pipe_fd(void)
40 return shm->pipe_fds[rand() % MAX_PIPE_FDS];
43 /* perf related fds (see also perf.c & syscalls/perf_event_open.c) */
44 static int rand_perf_fd(void)
46 return shm->perf_fds[rand() % MAX_PERF_FDS];
49 /* epoll related fds */
50 static void open_epoll_fds(void)
52 unsigned int i = 0;
53 int fd = -1;
55 while (i < MAX_EPOLL_FDS) {
57 switch (rand_bool()) {
58 case 0: fd = epoll_create(1);
59 break;
60 case 1: fd = epoll_create1(EPOLL_CLOEXEC);
61 break;
62 default:
63 break;
66 if (fd != -1) {
67 shm->epoll_fds[i] = fd;
68 output(2, "fd[%d] = epoll\n", shm->epoll_fds[i]);
69 i++;
74 static int rand_epoll_fd(void)
76 return shm->epoll_fds[rand() % MAX_EPOLL_FDS];
79 /* eventfd FDs */
80 static void open_eventfd_fds(void)
82 unsigned int i;
84 shm->eventfd_fds[0] = eventfd(rand32(), 0);
85 shm->eventfd_fds[1] = eventfd(rand32(), EFD_CLOEXEC);
86 shm->eventfd_fds[2] = eventfd(rand32(), EFD_NONBLOCK);
87 shm->eventfd_fds[3] = eventfd(rand32(), EFD_SEMAPHORE);
88 shm->eventfd_fds[4] = eventfd(rand32(), EFD_CLOEXEC | EFD_NONBLOCK);
89 shm->eventfd_fds[5] = eventfd(rand32(), EFD_CLOEXEC | EFD_SEMAPHORE);
90 shm->eventfd_fds[6] = eventfd(rand32(), EFD_NONBLOCK | EFD_SEMAPHORE);
91 shm->eventfd_fds[7] = eventfd(rand32(), EFD_CLOEXEC | EFD_NONBLOCK | EFD_SEMAPHORE);
93 for (i = 0; i < MAX_EVENTFD_FDS; i++)
94 output(2, "fd[%d] = eventfd\n", shm->eventfd_fds[i]);
97 static int rand_eventfd_fd(void)
99 return shm->eventfd_fds[rand() % MAX_EVENTFD_FDS];
102 /* regular file FDs */
103 unsigned int nr_file_fds = 0;
105 static int rand_file_fd(void)
107 unsigned int fd_index;
109 fd_index = rand() % nr_file_fds;
110 return shm->file_fds[fd_index];
114 static int get_new_random_fd(void)
116 unsigned int i;
117 int fd = 0;
119 retry:
120 i = rand() % 6;
122 if (do_specific_proto == TRUE)
123 i = 1;
125 if (no_files == TRUE)
126 i = 1;
128 /* Ugly special case.
129 * Sometimes, we can get here without any fd's setup.
130 * If this happens, we divide by zero if we pick case 0 because
131 * nr_file_fds is zero
133 * When this circumstance occurs, we just force it to use another network socket.
135 * FIXME: A better solution would be to like, actually open an fd. duh.
137 if (nr_file_fds == 0)
138 i = 1;
140 switch (i) {
141 case 0:
142 fd = rand_file_fd();
143 break;
145 case 1:
146 /* When using victim files, sockets can be 0.
147 * Use files as a fallback, or pipes if no files are open.
149 if (nr_sockets == 0) {
150 if (nr_file_fds > 0)
151 fd = rand_file_fd();
152 else
153 fd = rand_pipe_fd();
154 return fd;
156 fd = shm->socket_fds[rand() % nr_sockets];
157 break;
159 case 2:
160 fd = rand_pipe_fd();
161 break;
163 case 3:
164 if (shm->perf_fds[0] == 0) /* perf unavailable/disabled. */
165 goto retry;
167 fd = rand_perf_fd();
168 break;
170 case 4:
171 fd = rand_epoll_fd();
172 break;
174 case 5:
175 fd = rand_eventfd_fd();
176 break;
178 default:
179 break;
182 return fd;
185 int get_random_fd(void)
187 /* 25% chance of returning something new. */
188 if ((rand() % 4) == 0)
189 return get_new_random_fd();
191 /* the rest of the time, return the same fd as last time. */
192 regen:
193 if (shm->fd_lifetime == 0) {
194 shm->current_fd = get_new_random_fd();
195 shm->fd_lifetime = (rand() % shm->max_children) + 5;
196 } else
197 shm->fd_lifetime--;
199 if (shm->current_fd == 0) {
200 shm->fd_lifetime = 0;
201 goto regen;
204 return shm->current_fd;
207 void setup_fds(void)
209 open_sockets();
211 open_pipes();
213 open_perf_fds();
215 open_epoll_fds();
217 open_eventfd_fds();
219 if (no_files == FALSE) {
220 generate_filelist();
221 if (files_in_index == 0) /* Something bad happened. Crappy -V maybe? */
222 return; // FIXME: We should log something here probably.
224 open_files();
228 void regenerate_fds(void)
230 if (no_files == TRUE)
231 return;
233 close_files();
234 open_files();