Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Based on test by Dr. David Alan Gilbert <dave@treblig.org> |
| 3 | */ |
Dmitry V. Levin | 4960b2f | 2015-08-27 08:24:39 +0000 | [diff] [blame] | 4 | #include <stdio.h> |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 5 | #include <unistd.h> |
| 6 | #include <sys/select.h> |
Dmitry V. Levin | 10a4075 | 2015-09-18 21:45:36 +0000 | [diff] [blame^] | 7 | #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. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 18 | |
| 19 | static fd_set set[0x1000000 / sizeof(fd_set)]; |
| 20 | |
Dmitry V. Levin | 10a4075 | 2015-09-18 21:45:36 +0000 | [diff] [blame^] | 21 | int main(void) |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 22 | { |
| 23 | int fds[2]; |
Dmitry V. Levin | 100bf7c | 2015-09-18 21:37:09 +0000 | [diff] [blame] | 24 | struct { |
| 25 | struct timeval tv; |
| 26 | int pad[2]; |
| 27 | } tm = { |
| 28 | .tv = { .tv_usec = 123 }, |
| 29 | .pad = { 0xdeadbeef, 0xbadc0ded } |
| 30 | }; |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 31 | |
Dmitry V. Levin | 100bf7c | 2015-09-18 21:37:09 +0000 | [diff] [blame] | 32 | if (pipe(fds)) |
| 33 | return 77; |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 34 | |
| 35 | /* |
| 36 | * Start with a nice simple select. |
| 37 | */ |
| 38 | FD_ZERO(set); |
Dmitry V. Levin | 4960b2f | 2015-08-27 08:24:39 +0000 | [diff] [blame] | 39 | FD_SET(fds[0], set); |
| 40 | FD_SET(fds[1], set); |
Dmitry V. Levin | 10a4075 | 2015-09-18 21:45:36 +0000 | [diff] [blame^] | 41 | if (syscall(NR_select, fds[1] + 1, set, set, set, NULL) != 1) |
Dmitry V. Levin | 100bf7c | 2015-09-18 21:37:09 +0000 | [diff] [blame] | 42 | return 77; |
Dmitry V. Levin | 10a4075 | 2015-09-18 21:45:36 +0000 | [diff] [blame^] | 43 | 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. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 46 | |
| 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. Levin | 4960b2f | 2015-08-27 08:24:39 +0000 | [diff] [blame] | 52 | FD_SET(fds[1],set); |
Dmitry V. Levin | 10a4075 | 2015-09-18 21:45:36 +0000 | [diff] [blame^] | 53 | if (syscall(NR_select, -1, NULL, set, NULL, NULL) != -1) |
Dmitry V. Levin | 100bf7c | 2015-09-18 21:37:09 +0000 | [diff] [blame] | 54 | return 77; |
Dmitry V. Levin | 10a4075 | 2015-09-18 21:45:36 +0000 | [diff] [blame^] | 55 | printf("select(-1, NULL, %p, NULL, NULL) " |
| 56 | "= -1 EINVAL (Invalid argument)\n", set); |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 57 | |
| 58 | /* |
| 59 | * Another variant, with nfds exceeding FD_SETSIZE limit. |
| 60 | */ |
| 61 | FD_ZERO(set); |
Dmitry V. Levin | 4960b2f | 2015-08-27 08:24:39 +0000 | [diff] [blame] | 62 | FD_SET(fds[0],set); |
Dmitry V. Levin | 10a4075 | 2015-09-18 21:45:36 +0000 | [diff] [blame^] | 63 | if (syscall(NR_select, FD_SETSIZE + 1, set, set + 1, NULL, &tm.tv)) |
Dmitry V. Levin | 100bf7c | 2015-09-18 21:37:09 +0000 | [diff] [blame] | 64 | return 77; |
Dmitry V. Levin | 10a4075 | 2015-09-18 21:45:36 +0000 | [diff] [blame^] | 65 | printf("select(%d, [%d], [], NULL, {0, 123}) = 0 (Timeout)\n", |
| 66 | FD_SETSIZE + 1, fds[0]); |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 67 | |
Dmitry V. Levin | 4960b2f | 2015-08-27 08:24:39 +0000 | [diff] [blame] | 68 | puts("+++ exited with 0 +++"); |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 69 | return 0; |
| 70 | } |
Dmitry V. Levin | 10a4075 | 2015-09-18 21:45:36 +0000 | [diff] [blame^] | 71 | |
| 72 | #else |
| 73 | |
| 74 | int |
| 75 | main(void) |
| 76 | { |
| 77 | return 77; |
| 78 | } |
| 79 | |
| 80 | #endif |