1 /*-
2  * Copyright (c) 2007 Roman Divacky <pho@FreeBSD.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  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  */
27 
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <stdbool.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <string.h>
35 #include <sys/types.h>
36 #include <sys/syscall.h>
37 #include <sys/stat.h>
38 #include <sys/param.h>
39 
40 union param {
41 	int		i;
42 	char		*cp;
43 	mode_t		m;
44 	dev_t		d;
45 	void		*vp;
46 	uid_t		u;
47 	gid_t		g;
48 	char		**cpp;
49 };
50 
51 struct testcase {
52 	int		result;
53 	union param	params[5];	// no *at syscall with more than 5 params
54 };
55 
56 struct test {
57 	int	syscall;
58 	int	num_of_cases;
59 	char	*name;
60 	struct testcase	tests[10];	// no more than 10 tests
61 
62 };
63 
64 struct test *tests;
65 #define	NUM_OF_TESTS	15
66 
67 char *absolute_path = NULL;
68 char *relative_path = "tmp/";
69 char *not_dir_path = "/bin/date";
70 
71 char *file = "foo";
72 char *absolute_file = NULL;
73 char *relative_file = NULL;
74 char *symlinkf = "link";
75 char *newlink = "nlink1";
76 char *newlink2 = "nlink2";
77 char *newlink3 = "nlink3";
78 char *newdir = "newdir";
79 char *fifo = "fifo";
80 char *nod = "nod";
81 char *newfile = "newfile";
82 char *newslink = "nslink1";
83 
84 bool dir_exist = false;
85 bool file_exist = false;
86 bool link_exist = false;
87 
88 int rel_fd, abs_fd, notd_fd, exec_fd;
89 
90 struct timeval times[2];
91 struct stat buf;
92 char *pargv[2] = { "/bin/date", NULL };
93 char cbuf[PATH_MAX];
94 
95 void
96 setup()
97 {
98 	int i, error;
99 	struct stat sb;
100 
101 	tests = calloc(NUM_OF_TESTS, sizeof(struct test));
102 	if (tests == NULL) {
103 		perror("");
104 		exit(0);
105 	}
106 
107 	absolute_path = getcwd(NULL, 0);
108 	if (absolute_path == NULL) {
109 		perror("getcwd");
110 		exit(0);
111 	}
112 
113 	absolute_path = realloc(absolute_path, strlen(absolute_path) + 5);
114 	if (absolute_path == NULL) {
115 		perror("realloc");
116 		exit(0);
117 	}
118 
119 	strcat(absolute_path, "/");
120 	strcat(absolute_path, relative_path);
121 
122 	absolute_file = malloc(strlen(absolute_path) + 1 + strlen(file));
123 	bzero(absolute_file, strlen(absolute_path) + 1 + strlen(file));
124 	if (absolute_file == NULL) {
125 		perror("malloc");
126 		exit(0);
127 	}
128 	strcpy(absolute_file, absolute_path);
129 	absolute_file[strlen(absolute_file)] = '/';
130 	strcpy(absolute_file + strlen(absolute_path), file);
131 
132 	printf("XX: %s\n", absolute_file);
133 
134 	relative_file = malloc(strlen(relative_path) + 1 + strlen(file));
135 	bzero(relative_file, strlen(relative_path) + 1 + strlen(file));
136 	if (relative_file == NULL) {
137 		perror("malloc");
138 		exit(0);
139 	}
140 	strcpy(relative_file, relative_path);
141 	relative_file[strlen(relative_file)] = '/';
142 	strcpy(relative_file + strlen(relative_path), file);
143 
144 	printf("YY: %s\n", relative_file);
145 
146 	error = mkdir(relative_path, 0744);
147 	dir_exist = (errno == EEXIST);
148 	if (error && errno != EEXIST) {
149 		perror("tmp");
150 		exit(0);
151 	}
152 
153 	error = stat("tmp/foo", &sb);
154 	file_exist = (errno != ENOENT);
155 	i = open("tmp/foo", O_RDONLY | O_CREAT, 0644);
156 	if (i == -1) {
157 		perror("foo");
158 		exit(0);
159 	}
160 
161 	rel_fd = open(relative_path, O_RDONLY);
162 	if (rel_fd == -1) {
163 		perror("relative path");
164 		exit(0);
165 	}
166 
167 	abs_fd = open(absolute_path, O_RDONLY);
168 	if (abs_fd == -1) {
169 		perror("absolute path");
170 		exit(0);
171 	}
172 
173 	notd_fd = open(not_dir_path, O_RDONLY);
174 	if (notd_fd == -1) {
175 		perror("not a directory");
176 		exit(0);
177 	}
178 
179 	exec_fd = open(not_dir_path, O_RDONLY);
180 	if (exec_fd == -1) {
181 		perror("not a directory");
182 		exit(0);
183 	}
184 
185 	error = symlink(absolute_file, symlinkf);
186 	link_exist = (errno == EEXIST);
187 	if (error && errno != EEXIST) {
188 		perror("symlink");
189 		exit(0);
190 	}
191 
192 	// faccessat
193 	tests[0].syscall = SYS_faccessat;
194 	tests[0].num_of_cases = 6;
195 	tests[0].name = "faccessat";
196 	tests[0].tests[0].result = EBADF;
197 	tests[0].tests[0].params[0].i = 106;	// invalid fd
198 	tests[0].tests[0].params[1].cp = relative_path;
199 	tests[0].tests[0].params[2].m = 0;
200 	tests[0].tests[0].params[3].i = 0;
201 	tests[0].tests[1].result = EBADF;
202 	tests[0].tests[1].params[0].i = 106;	// invalid fd
203 	tests[0].tests[1].params[1].cp = relative_path;
204 	tests[0].tests[1].params[2].m = 0;
205 	tests[0].tests[1].params[3].i = AT_EACCESS;
206 	tests[0].tests[2].result = EINVAL;
207 	tests[0].tests[2].params[0].i = rel_fd;
208 	tests[0].tests[2].params[1].cp = absolute_path;
209 	tests[0].tests[2].params[2].m = 0;
210 	tests[0].tests[2].params[3].i = 123;	// invalid flag
211 	tests[0].tests[3].result = ENOTDIR;
212 	tests[0].tests[3].params[0].i = notd_fd;
213 	tests[0].tests[3].params[1].cp = relative_file;
214 	tests[0].tests[3].params[2].m = 0;
215 	tests[0].tests[3].params[3].i = 0;
216 	tests[0].tests[4].result = 0;
217 	tests[0].tests[4].params[0].i = rel_fd;
218 	tests[0].tests[4].params[1].cp = file;
219 	tests[0].tests[4].params[2].m = 0;
220 	tests[0].tests[4].params[3].i = 0;
221 	tests[0].tests[5].result = 0;
222 	tests[0].tests[5].params[0].i = rel_fd;
223 	tests[0].tests[5].params[1].cp = file;
224 	tests[0].tests[5].params[2].m = 0;
225 	tests[0].tests[5].params[3].i = AT_EACCESS;
226 	tests[0].tests[6].result = 0;
227 	tests[0].tests[6].params[0].i = 106;	// invalid fd
228 	tests[0].tests[6].params[1].cp = absolute_path;
229 	tests[0].tests[6].params[2].m = 0;
230 	tests[0].tests[6].params[3].i = 0;
231 
232 	// fchmodat
233 	tests[1].syscall = SYS_fchmodat;
234 	tests[1].num_of_cases = 6;
235 	tests[1].name = "fchmodat";
236 	tests[1].tests[0].result = EBADF;
237 	tests[1].tests[0].params[0].i = 106;	// invalid fd
238 	tests[1].tests[0].params[1].cp = relative_path;
239 	tests[1].tests[0].params[2].m = 33190;
240 	tests[1].tests[0].params[3].i = 0;
241 	tests[1].tests[1].result = EINVAL;
242 	tests[1].tests[1].params[0].i = rel_fd;
243 	tests[1].tests[1].params[1].cp = absolute_path;
244 	tests[1].tests[1].params[2].m = 33190;	// mode 646 translated
245 	tests[1].tests[1].params[3].i = 123;	// invalid flag
246 	tests[1].tests[2].result = ENOTDIR;
247 	tests[1].tests[2].params[0].i = notd_fd;
248 	tests[1].tests[2].params[1].cp = relative_file;
249 	tests[1].tests[2].params[2].m = 33190;
250 	tests[1].tests[2].params[3].i = 0;
251 	tests[1].tests[3].result = 0;
252 	tests[1].tests[3].params[0].i = notd_fd;
253 	tests[1].tests[3].params[1].cp = absolute_file;
254 	tests[1].tests[3].params[2].m = 33190;
255 	tests[1].tests[3].params[3].i = 0;
256 	tests[1].tests[4].result = 0;
257 	tests[1].tests[4].params[0].i = AT_FDCWD;
258 	tests[1].tests[4].params[1].cp = symlinkf;
259 	tests[1].tests[4].params[2].m = 33190;
260 	tests[1].tests[4].params[3].i = AT_SYMLINK_NOFOLLOW;
261 	tests[1].tests[5].result = 0;
262 	tests[1].tests[5].params[0].i = rel_fd;
263 	tests[1].tests[5].params[1].cp = file;
264 	tests[1].tests[5].params[2].m = 33190;
265 	tests[1].tests[5].params[3].i = 0;
266 
267 	// fchownat
268 	tests[2].syscall = SYS_fchownat;
269 	tests[2].num_of_cases = 6;
270 	tests[2].name = "fchownat";
271 	tests[2].tests[0].result = EBADF;
272 	tests[2].tests[0].params[0].i = 106;	// invalid fd
273 	tests[2].tests[0].params[1].cp = relative_file;
274 	tests[2].tests[0].params[2].u = 65534;
275 	tests[2].tests[0].params[3].g = 65534;
276 	tests[2].tests[0].params[4].i = 0;
277 	tests[2].tests[1].result = EINVAL;
278 	tests[2].tests[1].params[0].i = rel_fd;
279 	tests[2].tests[1].params[1].cp = file;
280 	tests[2].tests[1].params[2].u = 65534;
281 	tests[2].tests[1].params[3].g = 65534;
282 	tests[2].tests[1].params[4].i = 123;	// invalid flag
283 	tests[2].tests[2].result = ENOTDIR;
284 	tests[2].tests[2].params[0].i = notd_fd;
285 	tests[2].tests[2].params[1].cp = relative_file;
286 	tests[2].tests[2].params[2].u = 65534;
287 	tests[2].tests[2].params[3].g = 65534;
288 	tests[2].tests[2].params[4].i = 0;
289 	tests[2].tests[3].result = 0;
290 	tests[2].tests[3].params[0].i = notd_fd;
291 	tests[2].tests[3].params[1].cp = absolute_file;
292 	tests[2].tests[3].params[2].u = 65534;
293 	tests[2].tests[3].params[3].g = 65534;
294 	tests[2].tests[3].params[4].i = 0;
295 	tests[2].tests[4].result = 0;
296 	tests[2].tests[4].params[0].i = AT_FDCWD;
297 	tests[2].tests[4].params[1].cp = symlinkf;
298 	tests[2].tests[4].params[2].u = 65534;
299 	tests[2].tests[4].params[3].g = 65534;
300 	tests[2].tests[4].params[4].i = AT_SYMLINK_NOFOLLOW;
301 	tests[2].tests[5].result = 0;
302 	tests[2].tests[5].params[0].i = rel_fd;
303 	tests[2].tests[5].params[1].cp = file;
304 	tests[2].tests[5].params[2].u = 0;
305 	tests[2].tests[5].params[3].g = 0;
306 	tests[2].tests[5].params[4].i = 0;
307 
308 	// fstatat
309 	tests[3].syscall = SYS_fstatat;
310 	tests[3].num_of_cases = 5;
311 	tests[3].name = "fstatat";
312 	tests[3].tests[0].result = EBADF;
313 	tests[3].tests[0].params[0].i = 106;	// invalid fd
314 	tests[3].tests[0].params[1].cp = relative_file;
315 	tests[3].tests[0].params[2].vp = &buf;
316 	tests[3].tests[0].params[3].i = 0;
317 	tests[3].tests[1].result = EINVAL;
318 	tests[3].tests[1].params[0].i = rel_fd;
319 	tests[3].tests[1].params[1].cp = relative_file;
320 	tests[3].tests[1].params[2].vp = &buf;
321 	tests[3].tests[1].params[3].i = 123;	// invalid flags
322 	tests[3].tests[2].result = ENOTDIR;
323 	tests[3].tests[2].params[0].i = notd_fd;
324 	tests[3].tests[2].params[1].cp = relative_file;
325 	tests[3].tests[2].params[2].vp = &buf;
326 	tests[3].tests[2].params[3].i = 0;
327 	tests[3].tests[2].result = 0;
328 	tests[3].tests[2].params[0].i = rel_fd;
329 	tests[3].tests[2].params[1].cp = file;
330 	tests[3].tests[2].params[2].vp = &buf;
331 	tests[3].tests[2].params[3].i = 0;
332 	tests[3].tests[3].result = 0;
333 	tests[3].tests[3].params[0].i = AT_FDCWD;
334 	tests[3].tests[3].params[1].cp = symlinkf;
335 	tests[3].tests[3].params[2].vp = &buf;
336 	tests[3].tests[3].params[3].i = AT_SYMLINK_NOFOLLOW;
337 	tests[3].tests[4].result = 0;
338 	tests[3].tests[4].params[0].i = notd_fd;
339 	tests[3].tests[4].params[1].cp = absolute_file;
340 	tests[3].tests[4].params[2].vp = &buf;
341 	tests[3].tests[4].params[3].i = 0;
342 
343 	// futimesat
344 	tests[4].syscall = SYS_futimesat;
345 	tests[4].num_of_cases = 4;
346 	tests[4].name = "futimesat";
347 	tests[4].tests[0].result = EBADF;
348 	tests[4].tests[0].params[0].i = 106;	// invalid fd
349 	tests[4].tests[0].params[1].cp = relative_file;
350 	tests[4].tests[0].params[2].vp = times;
351 	tests[4].tests[1].result = ENOTDIR;
352 	tests[4].tests[1].params[0].i = notd_fd;
353 	tests[4].tests[1].params[1].cp = relative_file;
354 	tests[4].tests[1].params[2].vp = times;
355 	tests[4].tests[2].result = 0;
356 	tests[4].tests[2].params[0].i = rel_fd;
357 	tests[4].tests[2].params[1].cp = file;
358 	tests[4].tests[2].params[2].vp = times;
359 	tests[4].tests[3].result = 0;
360 	tests[4].tests[3].params[0].i = notd_fd;
361 	tests[4].tests[3].params[1].cp = absolute_file;
362 	tests[4].tests[3].params[2].vp = times;
363 
364 	// linkat
365 	tests[5].syscall = SYS_linkat;
366 	tests[5].num_of_cases = 7;
367 	tests[5].name = "linkat";
368 	tests[5].tests[0].result = EBADF;
369 	tests[5].tests[0].params[0].i = 106;	// invalid fd
370 	tests[5].tests[0].params[1].cp = relative_file;
371 	tests[5].tests[0].params[2].i = AT_FDCWD;
372 	tests[5].tests[0].params[3].cp = newlink;
373 	tests[5].tests[0].params[4].i = 0;
374 	tests[5].tests[1].result = EBADF;
375 	tests[5].tests[1].params[0].i = AT_FDCWD;
376 	tests[5].tests[1].params[1].cp = relative_file;
377 	tests[5].tests[1].params[2].i = 106;	// invalid fd
378 	tests[5].tests[1].params[3].cp = newlink;
379 	tests[5].tests[1].params[4].i = 0;
380 	tests[5].tests[2].result = EINVAL;
381 	tests[5].tests[2].params[0].i = rel_fd;
382 	tests[5].tests[2].params[1].cp = relative_file;
383 	tests[5].tests[2].params[2].i = AT_FDCWD;
384 	tests[5].tests[2].params[3].cp = newlink;
385 	tests[5].tests[2].params[4].i = 123;	// invalid flag
386 	tests[5].tests[3].result = ENOTDIR;
387 	tests[5].tests[3].params[0].i = notd_fd;
388 	tests[5].tests[3].params[1].cp = relative_file;
389 	tests[5].tests[3].params[2].i = AT_FDCWD;
390 	tests[5].tests[3].params[3].cp = newlink;
391 	tests[5].tests[3].params[4].i = 0;
392 	tests[5].tests[4].result = 0;
393 	tests[5].tests[4].params[0].i = rel_fd;
394 	tests[5].tests[4].params[1].cp = file;
395 	tests[5].tests[4].params[2].i = rel_fd;
396 	tests[5].tests[4].params[3].cp = newlink;
397 	tests[5].tests[4].params[4].i = 0;
398 	tests[5].tests[5].result = 0;
399 	tests[5].tests[5].params[0].i = AT_FDCWD;
400 	tests[5].tests[5].params[1].cp = symlinkf;
401 	tests[5].tests[5].params[2].i = rel_fd;
402 	tests[5].tests[5].params[3].cp = newlink2;
403 	tests[5].tests[5].params[4].i = 0;
404 	tests[5].tests[6].result = 0;
405 	tests[5].tests[6].params[0].i = AT_FDCWD;
406 	tests[5].tests[6].params[1].cp = symlinkf;
407 	tests[5].tests[6].params[2].i = rel_fd;
408 	tests[5].tests[6].params[3].cp = newlink3;
409 	tests[5].tests[6].params[4].i = AT_SYMLINK_FOLLOW;
410 
411 	// mkdirat
412 	tests[6].syscall = SYS_mkdirat;
413 	tests[6].num_of_cases = 3;
414 	tests[6].name = "mkdirat";
415 	tests[6].tests[0].result = EBADF;
416 	tests[6].tests[0].params[0].i = 106;	// invalid fd
417 	tests[6].tests[0].params[1].cp = relative_file;
418 	tests[6].tests[0].params[2].m = 33190;
419 	tests[6].tests[1].result = ENOTDIR;
420 	tests[6].tests[1].params[0].i = notd_fd;
421 	tests[6].tests[1].params[1].cp = relative_file;
422 	tests[6].tests[1].params[2].m = 33190;
423 	tests[6].tests[2].result = 0;
424 	tests[6].tests[2].params[0].i = rel_fd;
425 	tests[6].tests[2].params[1].cp = newdir;
426 	tests[6].tests[2].params[2].m = 33190;
427 
428 	// mkfifoat
429 	tests[7].syscall = SYS_mkfifoat;
430 	tests[7].num_of_cases = 3;
431 	tests[7].name = "mkfifoat";
432 	tests[7].tests[0].result = EBADF;
433 	tests[7].tests[0].params[0].i = 107;	// invalid fd
434 	tests[7].tests[0].params[1].cp = relative_file;
435 	tests[7].tests[0].params[2].m = 33190;
436 	tests[7].tests[1].result = ENOTDIR;
437 	tests[7].tests[1].params[0].i = notd_fd;
438 	tests[7].tests[1].params[1].cp = relative_file;
439 	tests[7].tests[1].params[2].m = 33190;
440 	tests[7].tests[2].result = 0;
441 	tests[7].tests[2].params[0].i = rel_fd;
442 	tests[7].tests[2].params[1].cp = fifo;
443 	tests[7].tests[2].params[2].m = 33190;
444 
445 	// mknodat
446 	tests[8].syscall = SYS_mknodat;
447 	tests[8].num_of_cases = 3;
448 	tests[8].name = "mknodat";
449 	tests[8].tests[0].result = EBADF;
450 	tests[8].tests[0].params[0].i = 108;	// invalid fd
451 	tests[8].tests[0].params[1].cp = relative_file;
452 	tests[8].tests[0].params[2].m = 0666 | S_IFCHR;
453 	tests[8].tests[0].params[3].d = 15;
454 	tests[8].tests[1].result = ENOTDIR;
455 	tests[8].tests[1].params[0].i = notd_fd;
456 	tests[8].tests[1].params[1].cp = relative_file;
457 	tests[8].tests[1].params[2].m = 0666 | S_IFCHR;
458 	tests[8].tests[1].params[3].d = 15;
459 	tests[8].tests[2].result = 0;
460 	tests[8].tests[2].params[0].i = rel_fd;
461 	tests[8].tests[2].params[1].cp = nod;
462 	tests[8].tests[2].params[2].m = 0666 | S_IFCHR;
463 	tests[8].tests[2].params[3].d = 2570;
464 
465 	// openat
466 	tests[9].syscall = SYS_openat;
467 	tests[9].num_of_cases = 5;
468 	tests[9].name = "openat";
469 	tests[9].tests[0].result = EBADF;
470 	tests[9].tests[0].params[0].i = 106;	// invalid fd
471 	tests[9].tests[0].params[1].cp = relative_file;
472 	tests[9].tests[0].params[2].i = O_RDONLY;
473 	tests[9].tests[0].params[3].i = 0666;
474 	tests[9].tests[1].result = ENOTDIR;
475 	tests[9].tests[1].params[0].i = notd_fd;
476 	tests[9].tests[1].params[1].cp = relative_file;
477 	tests[9].tests[1].params[2].i = O_RDONLY;
478 	tests[9].tests[1].params[3].i = 0666;
479 	tests[9].tests[2].result = 7;		// hardcoded fd
480 	tests[9].tests[2].params[0].i = rel_fd;
481 	tests[9].tests[2].params[1].cp = file;
482 	tests[9].tests[2].params[2].i = O_RDONLY;
483 	tests[9].tests[2].params[3].i = 0400;
484 	tests[9].tests[3].result = 8;		// hardcoded fd
485 	tests[9].tests[3].params[0].i = notd_fd;
486 	tests[9].tests[3].params[1].cp = absolute_file;
487 	tests[9].tests[3].params[2].i = O_RDONLY;
488 	tests[9].tests[3].params[3].i = 0400;
489 	tests[9].tests[4].result = 9;		// hardcoded fd
490 	tests[9].tests[4].params[0].i = rel_fd;
491 	tests[9].tests[4].params[1].cp = newfile;
492 	tests[9].tests[4].params[2].i = O_RDONLY | O_CREAT;
493 	tests[9].tests[4].params[3].i = 0666;
494 
495 	// readlinkat
496 	tests[10].syscall = SYS_readlinkat;
497 	tests[10].num_of_cases = 3;
498 	tests[10].name = "readlinkat";
499 	tests[10].tests[0].result = EBADF;
500 	tests[10].tests[0].params[0].i = 106;	// invalid fd
501 	tests[10].tests[0].params[1].cp = relative_file;
502 	tests[10].tests[0].params[2].vp = cbuf;
503 	tests[10].tests[0].params[3].i = PATH_MAX;
504 	tests[10].tests[1].result = ENOTDIR;
505 	tests[10].tests[1].params[0].i = notd_fd;
506 	tests[10].tests[1].params[1].cp = relative_file;
507 	tests[10].tests[1].params[2].vp = cbuf;
508 	tests[10].tests[1].params[3].i = PATH_MAX;
509 	tests[10].tests[2].result = strlen(absolute_file);
510 	tests[10].tests[2].params[0].i = AT_FDCWD;
511 	tests[10].tests[2].params[1].cp = symlinkf;
512 	tests[10].tests[2].params[2].vp = cbuf;
513 	tests[10].tests[2].params[3].i = PATH_MAX;
514 
515 	// renameat
516 	tests[11].syscall = SYS_renameat;
517 	tests[11].num_of_cases = 5;
518 	tests[11].name = "renameat";
519 	tests[11].tests[0].result = EBADF;
520 	tests[11].tests[0].params[0].i = 106;	// invalid fd
521 	tests[11].tests[0].params[1].cp = file;
522 	tests[11].tests[0].params[2].i = rel_fd;
523 	tests[11].tests[0].params[3].cp = file;
524 	tests[11].tests[1].result = EBADF;
525 	tests[11].tests[1].params[0].i = rel_fd;
526 	tests[11].tests[1].params[1].cp = file;
527 	tests[11].tests[1].params[2].i = 106;	// invalid fd
528 	tests[11].tests[1].params[3].cp = file;
529 	tests[11].tests[2].result = ENOTDIR;
530 	tests[11].tests[2].params[0].i = notd_fd;
531 	tests[11].tests[2].params[1].cp = relative_file;
532 	tests[11].tests[2].params[2].i = rel_fd;
533 	tests[11].tests[2].params[3].cp = file;
534 	tests[11].tests[3].result = ENOTDIR;
535 	tests[11].tests[3].params[0].i = rel_fd;
536 	tests[11].tests[3].params[1].cp = file;
537 	tests[11].tests[3].params[2].i = notd_fd;
538 	tests[11].tests[3].params[3].cp = relative_file;
539 	tests[11].tests[4].result = 0;
540 	tests[11].tests[4].params[0].i = rel_fd;
541 	tests[11].tests[4].params[1].cp = newfile;
542 	tests[11].tests[4].params[2].i = AT_FDCWD;
543 	tests[11].tests[4].params[3].cp = newfile;
544 
545 	// symlinkat
546 	tests[12].syscall = SYS_symlinkat;
547 	tests[12].num_of_cases = 3;
548 	tests[12].name = "symlinkat";
549 	tests[12].tests[0].result = EBADF;
550 	tests[12].tests[0].params[0].cp = file;
551 	tests[12].tests[0].params[1].i = 106;	// invalid fd
552 	tests[12].tests[0].params[2].cp = file;
553 	tests[12].tests[1].result = ENOTDIR;
554 	tests[12].tests[1].params[0].cp = file;
555 	tests[12].tests[1].params[1].i = notd_fd;
556 	tests[12].tests[1].params[2].cp = relative_file;
557 	tests[12].tests[2].result = 0;
558 	tests[12].tests[2].params[0].cp = absolute_file;
559 	tests[12].tests[2].params[1].i = rel_fd;
560 	tests[12].tests[2].params[2].cp = newslink;
561 
562 
563 	// unlinkat
564 	tests[13].syscall = SYS_unlinkat;
565 	tests[13].num_of_cases = 7;
566 	tests[13].name = "unlinkat";
567 	tests[13].tests[0].result = EBADF;
568 	tests[13].tests[0].params[0].i = 106;	// invalid fd
569 	tests[13].tests[0].params[1].cp = relative_file;
570 	tests[13].tests[0].params[2].i = 0;
571 	tests[13].tests[1].result = ENOTDIR;
572 	tests[13].tests[1].params[0].i = notd_fd;
573 	tests[13].tests[1].params[1].cp = relative_file;
574 	tests[13].tests[1].params[2].i = 0;
575 	tests[13].tests[2].result = EINVAL;
576 	tests[13].tests[2].params[0].i = rel_fd;
577 	tests[13].tests[2].params[1].cp = file;
578 	tests[13].tests[2].params[2].i = 123;	// invalid flag
579 	tests[13].tests[3].result = ENOTDIR;
580 	tests[13].tests[3].params[0].i = rel_fd;
581 	tests[13].tests[3].params[1].cp = not_dir_path;
582 	tests[13].tests[3].params[2].i = AT_REMOVEDIR;
583 	tests[13].tests[4].result = ENOTEMPTY;
584 	tests[13].tests[4].params[0].i = AT_FDCWD;
585 	tests[13].tests[4].params[1].cp = relative_path;
586 	tests[13].tests[4].params[2].i = AT_REMOVEDIR;
587 	tests[13].tests[5].result = 0;
588 	tests[13].tests[5].params[0].i = rel_fd;
589 	tests[13].tests[5].params[1].cp = newdir;
590 	tests[13].tests[5].params[2].i = AT_REMOVEDIR;
591 	tests[13].tests[6].result = 0;
592 	tests[13].tests[6].params[0].i = AT_FDCWD;
593 	tests[13].tests[6].params[1].cp = newfile;
594 	tests[13].tests[6].params[2].i = 0;
595 
596 
597 	// fexecve
598 	tests[14].syscall = SYS_fexecve;
599 	tests[14].num_of_cases = 2;
600 	tests[14].name = "fexecve";
601 	tests[14].tests[0].result = EBADF;
602 	tests[14].tests[0].params[0].i = 106;	// invalid fd
603 	tests[14].tests[0].params[1].cpp = pargv;
604 	tests[14].tests[0].params[2].cpp = NULL;
605 	// This is EXPECTED to execve /bin/date, so dont expect OK output
606 	tests[14].tests[1].result = 0;
607 	tests[14].tests[1].params[0].i = exec_fd;
608 	tests[14].tests[1].params[1].cpp = pargv;
609 	tests[14].tests[1].params[2].cpp = NULL;
610 }
611 
612 void
613 cleanup()
614 {
615 	int error;
616 
617 	close(notd_fd);
618 	close(rel_fd);
619 	close(abs_fd);
620 
621 	if (!file_exist) {
622 		error = unlink("tmp/foo");
623 		if (error) {
624 			perror("unlink");
625 			exit(0);
626 		}
627 	}
628 	if (!dir_exist) {
629 		error = rmdir(absolute_path);
630 		if (error) {
631 			perror("rmdir");
632 			exit(0);
633 		}
634 	}
635 	if (link_exist) {
636 		error = unlink(symlinkf);
637 		if (error) {
638 			perror("unlink");
639 			exit(0);
640 		}
641 	}
642 }
643 
644 void
645 setup_once()
646 {
647 }
648 
649 int
650 main(int argc, char *argv[])
651 {
652 	int i,j;
653 	int error;
654 
655 	setup();
656 
657 	for (i = 0; i < NUM_OF_TESTS; i++) {
658 		printf("\nTest: %s\n", tests[i].name);
659 		for (j = 0; j < tests[i].num_of_cases; j++) {
660 			error = syscall(tests[i].syscall,
661 				tests[i].tests[j].params[0],
662 				tests[i].tests[j].params[1],
663 				tests[i].tests[j].params[2],
664 				tests[i].tests[j].params[3],
665 				tests[i].tests[j].params[4]);
666 			if (error == 0) {
667 				if (tests[i].tests[j].result == 0)
668 					printf("#%i ... OK\n", j);
669 				else {
670 					printf("#%i ... BAD: ", j);
671 					printf("expected %i, but got %i\n", tests[i].tests[j].result, error);
672 				}
673 			} else {
674 				if (tests[i].tests[j].result == errno)
675 					printf("#%i ... OK\n", j);
676 				else {
677 					if (error != tests[i].tests[j].result) {
678 						printf("#%i ... BAD: ", j);
679 						printf("expected %i, but got %i\n", tests[i].tests[j].result, error);
680 					} else
681 						printf("#%i ... OK\n", j);
682 				}
683 			}
684 
685 
686 		}
687 	}
688 
689 //	cleanup();
690 
691 
692 	return (0);
693 }
694