blob: 0f8f6cb8ea5aa2f3110dfc5e134db04718860515 [file] [log] [blame]
Dmitry V. Levine837b142015-02-04 02:09:52 +00001/*
Dmitry V. Levin39e3be62015-09-18 21:54:52 +00002 * Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28/*
Dmitry V. Levine837b142015-02-04 02:09:52 +000029 * Based on test by Dr. David Alan Gilbert <dave@treblig.org>
30 */
Dmitry V. Levin4960b2f2015-08-27 08:24:39 +000031#include <stdio.h>
Dmitry V. Levine837b142015-02-04 02:09:52 +000032#include <unistd.h>
33#include <sys/select.h>
Dmitry V. Levin10a40752015-09-18 21:45:36 +000034#include <sys/syscall.h>
35
36#undef NR_select
37
38#if defined __NR__newselect
39# define NR_select __NR__newselect
40#elif defined __NR_select
41# define NR_select __NR_select
42#endif
43
44#ifdef NR_select
Dmitry V. Levine837b142015-02-04 02:09:52 +000045
46static fd_set set[0x1000000 / sizeof(fd_set)];
47
Dmitry V. Levin10a40752015-09-18 21:45:36 +000048int main(void)
Dmitry V. Levine837b142015-02-04 02:09:52 +000049{
50 int fds[2];
Dmitry V. Levin100bf7c2015-09-18 21:37:09 +000051 struct {
52 struct timeval tv;
53 int pad[2];
Dmitry V. Levin39e3be62015-09-18 21:54:52 +000054 } tm_in = {
55 .tv = { .tv_sec = 0xc0de1, .tv_usec = 0xc0de2 },
Dmitry V. Levin100bf7c2015-09-18 21:37:09 +000056 .pad = { 0xdeadbeef, 0xbadc0ded }
Dmitry V. Levin39e3be62015-09-18 21:54:52 +000057 }, tm = tm_in;
Dmitry V. Levine837b142015-02-04 02:09:52 +000058
Dmitry V. Levin100bf7c2015-09-18 21:37:09 +000059 if (pipe(fds))
60 return 77;
Dmitry V. Levine837b142015-02-04 02:09:52 +000061
62 /*
63 * Start with a nice simple select.
64 */
65 FD_ZERO(set);
Dmitry V. Levin4960b2f2015-08-27 08:24:39 +000066 FD_SET(fds[0], set);
67 FD_SET(fds[1], set);
Dmitry V. Levin10a40752015-09-18 21:45:36 +000068 if (syscall(NR_select, fds[1] + 1, set, set, set, NULL) != 1)
Dmitry V. Levin100bf7c2015-09-18 21:37:09 +000069 return 77;
Dmitry V. Levin10a40752015-09-18 21:45:36 +000070 printf("select(%d, [%d %d], [%d %d], [%d %d], NULL) = 1 ()\n",
71 fds[1] + 1, fds[0], fds[1],
72 fds[0], fds[1], fds[0], fds[1]);
Dmitry V. Levine837b142015-02-04 02:09:52 +000073
74 /*
Dmitry V. Levin39e3be62015-09-18 21:54:52 +000075 * Another simple one, with a timeout.
76 */
77 FD_SET(1, set);
78 FD_SET(2, set);
79 FD_SET(fds[0], set);
80 FD_SET(fds[1], set);
81 if (syscall(NR_select, fds[1] + 1, NULL, set, NULL, &tm.tv) != 3)
82 return 77;
83 printf("select(%d, NULL, [1 2 %d %d], NULL, {%Ld, %Ld})"
84 " = 3 (out [1 2 %d], left {%Ld, %Ld})\n",
85 fds[1] + 1, fds[0], fds[1],
86 (long long) tm_in.tv.tv_sec, (long long) tm_in.tv.tv_usec,
87 fds[1],
88 (long long) tm.tv.tv_sec, (long long) tm.tv.tv_usec);
89
90 /*
Dmitry V. Levine837b142015-02-04 02:09:52 +000091 * Now the crash case that trinity found, negative nfds
92 * but with a pointer to a large chunk of valid memory.
93 */
94 FD_ZERO(set);
Dmitry V. Levin4960b2f2015-08-27 08:24:39 +000095 FD_SET(fds[1],set);
Dmitry V. Levin10a40752015-09-18 21:45:36 +000096 if (syscall(NR_select, -1, NULL, set, NULL, NULL) != -1)
Dmitry V. Levin100bf7c2015-09-18 21:37:09 +000097 return 77;
Dmitry V. Levin10a40752015-09-18 21:45:36 +000098 printf("select(-1, NULL, %p, NULL, NULL) "
99 "= -1 EINVAL (Invalid argument)\n", set);
Dmitry V. Levine837b142015-02-04 02:09:52 +0000100
101 /*
102 * Another variant, with nfds exceeding FD_SETSIZE limit.
103 */
104 FD_ZERO(set);
Dmitry V. Levin4960b2f2015-08-27 08:24:39 +0000105 FD_SET(fds[0],set);
Dmitry V. Levin39e3be62015-09-18 21:54:52 +0000106 tm.tv.tv_sec = 0;
107 tm.tv.tv_usec = 123;
Dmitry V. Levin10a40752015-09-18 21:45:36 +0000108 if (syscall(NR_select, FD_SETSIZE + 1, set, set + 1, NULL, &tm.tv))
Dmitry V. Levin100bf7c2015-09-18 21:37:09 +0000109 return 77;
Dmitry V. Levin10a40752015-09-18 21:45:36 +0000110 printf("select(%d, [%d], [], NULL, {0, 123}) = 0 (Timeout)\n",
111 FD_SETSIZE + 1, fds[0]);
Dmitry V. Levine837b142015-02-04 02:09:52 +0000112
Dmitry V. Levin4960b2f2015-08-27 08:24:39 +0000113 puts("+++ exited with 0 +++");
Dmitry V. Levine837b142015-02-04 02:09:52 +0000114 return 0;
115}
Dmitry V. Levin10a40752015-09-18 21:45:36 +0000116
117#else
118
119int
120main(void)
121{
122 return 77;
123}
124
125#endif