blob: db87704ed1e352c74c7113c5bac2c97d5c85fef5 [file] [log] [blame]
Dmitry V. Levine837b142015-02-04 02:09:52 +00001/*
2 * Based on test by Dr. David Alan Gilbert <dave@treblig.org>
3 */
Dmitry V. Levin4960b2f2015-08-27 08:24:39 +00004#include <stdio.h>
Dmitry V. Levine837b142015-02-04 02:09:52 +00005#include <unistd.h>
6#include <sys/select.h>
Dmitry V. Levin10a40752015-09-18 21:45:36 +00007#include <sys/syscall.h>
8
9#undef NR_select
10
11#if defined __NR__newselect
12# define NR_select __NR__newselect
13#elif defined __NR_select
14# define NR_select __NR_select
15#endif
16
17#ifdef NR_select
Dmitry V. Levine837b142015-02-04 02:09:52 +000018
19static fd_set set[0x1000000 / sizeof(fd_set)];
20
Dmitry V. Levin10a40752015-09-18 21:45:36 +000021int main(void)
Dmitry V. Levine837b142015-02-04 02:09:52 +000022{
23 int fds[2];
Dmitry V. Levin100bf7c2015-09-18 21:37:09 +000024 struct {
25 struct timeval tv;
26 int pad[2];
27 } tm = {
28 .tv = { .tv_usec = 123 },
29 .pad = { 0xdeadbeef, 0xbadc0ded }
30 };
Dmitry V. Levine837b142015-02-04 02:09:52 +000031
Dmitry V. Levin100bf7c2015-09-18 21:37:09 +000032 if (pipe(fds))
33 return 77;
Dmitry V. Levine837b142015-02-04 02:09:52 +000034
35 /*
36 * Start with a nice simple select.
37 */
38 FD_ZERO(set);
Dmitry V. Levin4960b2f2015-08-27 08:24:39 +000039 FD_SET(fds[0], set);
40 FD_SET(fds[1], set);
Dmitry V. Levin10a40752015-09-18 21:45:36 +000041 if (syscall(NR_select, fds[1] + 1, set, set, set, NULL) != 1)
Dmitry V. Levin100bf7c2015-09-18 21:37:09 +000042 return 77;
Dmitry V. Levin10a40752015-09-18 21:45:36 +000043 printf("select(%d, [%d %d], [%d %d], [%d %d], NULL) = 1 ()\n",
44 fds[1] + 1, fds[0], fds[1],
45 fds[0], fds[1], fds[0], fds[1]);
Dmitry V. Levine837b142015-02-04 02:09:52 +000046
47 /*
48 * Now the crash case that trinity found, negative nfds
49 * but with a pointer to a large chunk of valid memory.
50 */
51 FD_ZERO(set);
Dmitry V. Levin4960b2f2015-08-27 08:24:39 +000052 FD_SET(fds[1],set);
Dmitry V. Levin10a40752015-09-18 21:45:36 +000053 if (syscall(NR_select, -1, NULL, set, NULL, NULL) != -1)
Dmitry V. Levin100bf7c2015-09-18 21:37:09 +000054 return 77;
Dmitry V. Levin10a40752015-09-18 21:45:36 +000055 printf("select(-1, NULL, %p, NULL, NULL) "
56 "= -1 EINVAL (Invalid argument)\n", set);
Dmitry V. Levine837b142015-02-04 02:09:52 +000057
58 /*
59 * Another variant, with nfds exceeding FD_SETSIZE limit.
60 */
61 FD_ZERO(set);
Dmitry V. Levin4960b2f2015-08-27 08:24:39 +000062 FD_SET(fds[0],set);
Dmitry V. Levin10a40752015-09-18 21:45:36 +000063 if (syscall(NR_select, FD_SETSIZE + 1, set, set + 1, NULL, &tm.tv))
Dmitry V. Levin100bf7c2015-09-18 21:37:09 +000064 return 77;
Dmitry V. Levin10a40752015-09-18 21:45:36 +000065 printf("select(%d, [%d], [], NULL, {0, 123}) = 0 (Timeout)\n",
66 FD_SETSIZE + 1, fds[0]);
Dmitry V. Levine837b142015-02-04 02:09:52 +000067
Dmitry V. Levin4960b2f2015-08-27 08:24:39 +000068 puts("+++ exited with 0 +++");
Dmitry V. Levine837b142015-02-04 02:09:52 +000069 return 0;
70}
Dmitry V. Levin10a40752015-09-18 21:45:36 +000071
72#else
73
74int
75main(void)
76{
77 return 77;
78}
79
80#endif