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 | */ |
| 4 | #include <assert.h> |
Dmitry V. Levin | 4960b2f | 2015-08-27 08:24:39 +0000 | [diff] [blame^] | 5 | #include <stdio.h> |
| 6 | #include <string.h> |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 7 | #include <unistd.h> |
| 8 | #include <sys/select.h> |
| 9 | |
| 10 | static fd_set set[0x1000000 / sizeof(fd_set)]; |
| 11 | |
Dmitry V. Levin | 4960b2f | 2015-08-27 08:24:39 +0000 | [diff] [blame^] | 12 | int main(int ac, char **av) |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 13 | { |
| 14 | int fds[2]; |
| 15 | struct timeval timeout = { .tv_sec = 0, .tv_usec = 100 }; |
Dmitry V. Levin | 4960b2f | 2015-08-27 08:24:39 +0000 | [diff] [blame^] | 16 | int is_select = ac < 2 || strcmp(av[1], "pselect6"); |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 17 | |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 18 | assert(pipe(fds) == 0); |
| 19 | |
| 20 | /* |
| 21 | * Start with a nice simple select. |
| 22 | */ |
| 23 | FD_ZERO(set); |
Dmitry V. Levin | 4960b2f | 2015-08-27 08:24:39 +0000 | [diff] [blame^] | 24 | FD_SET(fds[0], set); |
| 25 | FD_SET(fds[1], set); |
| 26 | assert(select(fds[1] + 1, set, set, set, NULL) == 1); |
| 27 | if (is_select) |
| 28 | printf("select(%d, [%d %d], [%d %d], [%d %d], NULL) = 1 ()\n", |
| 29 | fds[1] + 1, fds[0], fds[1], |
| 30 | fds[0], fds[1], fds[0], fds[1]); |
| 31 | else |
| 32 | printf("pselect6(%d, [%d %d], [%d %d], [%d %d], NULL, NULL) " |
| 33 | "= 1 ()\n", |
| 34 | fds[1] + 1, fds[0], fds[1], |
| 35 | fds[0], fds[1], fds[0], fds[1]); |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 36 | |
| 37 | /* |
| 38 | * Now the crash case that trinity found, negative nfds |
| 39 | * but with a pointer to a large chunk of valid memory. |
| 40 | */ |
| 41 | FD_ZERO(set); |
Dmitry V. Levin | 4960b2f | 2015-08-27 08:24:39 +0000 | [diff] [blame^] | 42 | FD_SET(fds[1],set); |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 43 | assert(select(-1, NULL, set, NULL, NULL) == -1); |
Dmitry V. Levin | 4960b2f | 2015-08-27 08:24:39 +0000 | [diff] [blame^] | 44 | if (is_select) |
| 45 | printf("select(-1, NULL, %p, NULL, NULL) " |
| 46 | "= -1 EINVAL (Invalid argument)\n", set); |
| 47 | else |
| 48 | printf("pselect6(-1, NULL, %p, NULL, NULL, NULL) " |
| 49 | "= -1 EINVAL (Invalid argument)\n", set); |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 50 | |
| 51 | /* |
| 52 | * Another variant, with nfds exceeding FD_SETSIZE limit. |
| 53 | */ |
| 54 | FD_ZERO(set); |
Dmitry V. Levin | 4960b2f | 2015-08-27 08:24:39 +0000 | [diff] [blame^] | 55 | FD_SET(fds[0],set); |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 56 | assert(select(FD_SETSIZE + 1, set, set + 1, NULL, &timeout) == 0); |
Dmitry V. Levin | 4960b2f | 2015-08-27 08:24:39 +0000 | [diff] [blame^] | 57 | if (is_select) |
| 58 | printf("select(%d, [%d], [], NULL, {0, 100}) = 0 (Timeout)\n", |
| 59 | FD_SETSIZE + 1, fds[0]); |
| 60 | else |
| 61 | printf("pselect6(%d, [%d], [], NULL, {0, 100000}, NULL) " |
| 62 | "= 0 (Timeout)\n", FD_SETSIZE + 1, fds[0]); |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 63 | |
Dmitry V. Levin | 4960b2f | 2015-08-27 08:24:39 +0000 | [diff] [blame^] | 64 | puts("+++ exited with 0 +++"); |
Dmitry V. Levin | e837b14 | 2015-02-04 02:09:52 +0000 | [diff] [blame] | 65 | return 0; |
| 66 | } |