1 //===-- stubs.c -----------------------------------------------------------===//
2 //
3 // The KLEE Symbolic Virtual Machine
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifdef __FreeBSD__
11 #include "FreeBSD.h"
12 #endif
13 #include <errno.h>
14 #include <limits.h>
15 #include <signal.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <time.h>
20 #include <unistd.h>
21 #include <utime.h>
22 #ifndef __FreeBSD__
23 #include <utmp.h>
24 #endif
25 #include <sys/mman.h>
26 #include <sys/resource.h>
27 #include <sys/stat.h>
28 #include <sys/time.h>
29 #include <sys/times.h>
30 #include <sys/types.h>
31 #include <sys/wait.h>
32
33 #include "klee/Config/config.h"
34
35 void klee_warning(const char*);
36 void klee_warning_once(const char*);
37
38 /* Silent ignore */
39
40 int __syscall_rt_sigaction(int signum, const struct sigaction *act,
41 struct sigaction *oldact, size_t _something)
42 __attribute__((weak));
43
__syscall_rt_sigaction(int signum,const struct sigaction * act,struct sigaction * oldact,size_t _something)44 int __syscall_rt_sigaction(int signum, const struct sigaction *act,
45 struct sigaction *oldact, size_t _something) {
46 klee_warning_once("silently ignoring");
47 return 0;
48 }
49
50 int sigaction(int signum, const struct sigaction *act,
51 struct sigaction *oldact) __attribute__((weak));
52
sigaction(int signum,const struct sigaction * act,struct sigaction * oldact)53 int sigaction(int signum, const struct sigaction *act,
54 struct sigaction *oldact) {
55 klee_warning_once("silently ignoring");
56 return 0;
57 }
58
59 int sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
60 __attribute__((weak));
sigprocmask(int how,const sigset_t * set,sigset_t * oldset)61 int sigprocmask(int how, const sigset_t *set, sigset_t *oldset) {
62 klee_warning_once("silently ignoring");
63 return 0;
64 }
65
66 /* Not even worth warning about these */
67 int fdatasync(int fd) __attribute__((weak));
fdatasync(int fd)68 int fdatasync(int fd) {
69 return 0;
70 }
71
72 /* Not even worth warning about this */
73 void sync(void) __attribute__((weak));
sync(void)74 void sync(void) {
75 }
76
77 /* Error ignore */
78
79 extern int __fgetc_unlocked(FILE *f);
80 extern int __fputc_unlocked(int c, FILE *f);
81
82 int __socketcall(int type, int *args) __attribute__((weak));
__socketcall(int type,int * args)83 int __socketcall(int type, int *args) {
84 klee_warning("ignoring (EAFNOSUPPORT)");
85 errno = EAFNOSUPPORT;
86 return -1;
87 }
88
89 int _IO_getc(FILE *f) __attribute__((weak));
_IO_getc(FILE * f)90 int _IO_getc(FILE *f) {
91 return __fgetc_unlocked(f);
92 }
93
94 int _IO_putc(int c, FILE *f) __attribute__((weak));
_IO_putc(int c,FILE * f)95 int _IO_putc(int c, FILE *f) {
96 return __fputc_unlocked(c, f);
97 }
98
99 int mkdir(const char *pathname, mode_t mode) __attribute__((weak));
mkdir(const char * pathname,mode_t mode)100 int mkdir(const char *pathname, mode_t mode) {
101 klee_warning("ignoring (EIO)");
102 errno = EIO;
103 return -1;
104 }
105
106 int mkfifo(const char *pathname, mode_t mode) __attribute__((weak));
mkfifo(const char * pathname,mode_t mode)107 int mkfifo(const char *pathname, mode_t mode) {
108 klee_warning("ignoring (EIO)");
109 errno = EIO;
110 return -1;
111 }
112
113 int mknod(const char *pathname, mode_t mode, dev_t dev) __attribute__((weak));
mknod(const char * pathname,mode_t mode,dev_t dev)114 int mknod(const char *pathname, mode_t mode, dev_t dev) {
115 klee_warning("ignoring (EIO)");
116 errno = EIO;
117 return -1;
118 }
119
120 int pipe(int filedes[2]) __attribute__((weak));
pipe(int filedes[2])121 int pipe(int filedes[2]) {
122 klee_warning("ignoring (ENFILE)");
123 errno = ENFILE;
124 return -1;
125 }
126
127 int link(const char *oldpath, const char *newpath) __attribute__((weak));
link(const char * oldpath,const char * newpath)128 int link(const char *oldpath, const char *newpath) {
129 klee_warning("ignoring (EPERM)");
130 errno = EPERM;
131 return -1;
132 }
133
134 int symlink(const char *oldpath, const char *newpath) __attribute__((weak));
symlink(const char * oldpath,const char * newpath)135 int symlink(const char *oldpath, const char *newpath) {
136 klee_warning("ignoring (EPERM)");
137 errno = EPERM;
138 return -1;
139 }
140
141 int rename(const char *oldpath, const char *newpath) __attribute__((weak));
rename(const char * oldpath,const char * newpath)142 int rename(const char *oldpath, const char *newpath) {
143 klee_warning("ignoring (EPERM)");
144 errno = EPERM;
145 return -1;
146 }
147
148 int nanosleep(const struct timespec *req, struct timespec *rem) __attribute__((weak));
nanosleep(const struct timespec * req,struct timespec * rem)149 int nanosleep(const struct timespec *req, struct timespec *rem) {
150 return 0;
151 }
152
153 /* XXX why can't I call this internally? */
154 int clock_gettime(clockid_t clk_id, struct timespec *res) __attribute__((weak));
clock_gettime(clockid_t clk_id,struct timespec * res)155 int clock_gettime(clockid_t clk_id, struct timespec *res) {
156 /* Fake */
157 struct timeval tv;
158 gettimeofday(&tv, NULL);
159 res->tv_sec = tv.tv_sec;
160 res->tv_nsec = tv.tv_usec * 1000;
161 return 0;
162 }
163
164 int clock_settime(clockid_t clk_id, const struct timespec *res) __attribute__((weak));
clock_settime(clockid_t clk_id,const struct timespec * res)165 int clock_settime(clockid_t clk_id, const struct timespec *res) {
166 klee_warning("ignoring (EPERM)");
167 errno = EPERM;
168 return -1;
169 }
170
time(time_t * t)171 time_t time(time_t *t) {
172 struct timeval tv;
173 gettimeofday(&tv, NULL);
174 if (t)
175 *t = tv.tv_sec;
176 return tv.tv_sec;
177 }
178
times(struct tms * buf)179 clock_t times(struct tms *buf) {
180 /* Fake */
181 if (!buf)
182 klee_warning("returning 0\n");
183 else {
184 klee_warning("setting all times to 0 and returning 0\n");
185 buf->tms_utime = 0;
186 buf->tms_stime = 0;
187 buf->tms_cutime = 0;
188 buf->tms_cstime = 0;
189 }
190 return 0;
191 }
192
193 #ifndef __FreeBSD__
194 struct utmpx *getutxent(void) __attribute__((weak));
getutxent(void)195 struct utmpx *getutxent(void) {
196 return (struct utmpx*) getutent();
197 }
198
199 void setutxent(void) __attribute__((weak));
setutxent(void)200 void setutxent(void) {
201 setutent();
202 }
203
204 void endutxent(void) __attribute__((weak));
endutxent(void)205 void endutxent(void) {
206 endutent();
207 }
208
209 int utmpxname(const char *file) __attribute__((weak));
utmpxname(const char * file)210 int utmpxname(const char *file) {
211 utmpname(file);
212 return 0;
213 }
214 #endif
215
216 int euidaccess(const char *pathname, int mode) __attribute__((weak));
euidaccess(const char * pathname,int mode)217 int euidaccess(const char *pathname, int mode) {
218 return access(pathname, mode);
219 }
220
221 int eaccess(const char *pathname, int mode) __attribute__((weak));
eaccess(const char * pathname,int mode)222 int eaccess(const char *pathname, int mode) {
223 return euidaccess(pathname, mode);
224 }
225
226 int group_member (gid_t __gid) __attribute__((weak));
group_member(gid_t __gid)227 int group_member (gid_t __gid) {
228 return ((__gid == getgid ()) || (__gid == getegid ()));
229 }
230
231 int utime(const char *filename, const struct utimbuf *buf) __attribute__((weak));
utime(const char * filename,const struct utimbuf * buf)232 int utime(const char *filename, const struct utimbuf *buf) {
233 klee_warning("ignoring (EPERM)");
234 errno = EPERM;
235 return -1;
236 }
237
238 int futimes(int fd, const struct timeval times[2]) __attribute__((weak));
futimes(int fd,const struct timeval times[2])239 int futimes(int fd, const struct timeval times[2]) {
240 klee_warning("ignoring (EBADF)");
241 errno = EBADF;
242 return -1;
243 }
244
strverscmp(__const char * __s1,__const char * __s2)245 int strverscmp (__const char *__s1, __const char *__s2) {
246 return strcmp(__s1, __s2); /* XXX no doubt this is bad */
247 }
248
249 #if __GLIBC_PREREQ(2, 25)
250 #define gnu_dev_type dev_t
251 #else
252 #define gnu_dev_type unsigned long long int
253 #endif
254
255 unsigned int gnu_dev_major(gnu_dev_type __dev) __attribute__((weak));
gnu_dev_major(gnu_dev_type __dev)256 unsigned int gnu_dev_major(gnu_dev_type __dev) {
257 return ((__dev >> 8) & 0xfff) | ((unsigned int) (__dev >> 32) & ~0xfff);
258 }
259
260 unsigned int gnu_dev_minor(gnu_dev_type __dev) __attribute__((weak));
gnu_dev_minor(gnu_dev_type __dev)261 unsigned int gnu_dev_minor(gnu_dev_type __dev) {
262 return (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff);
263 }
264
265 gnu_dev_type gnu_dev_makedev(unsigned int __major, unsigned int __minor) __attribute__((weak));
gnu_dev_makedev(unsigned int __major,unsigned int __minor)266 gnu_dev_type gnu_dev_makedev(unsigned int __major, unsigned int __minor) {
267 return ((__minor & 0xff) | ((__major & 0xfff) << 8)
268 | (((gnu_dev_type) (__minor & ~0xff)) << 12)
269 | (((gnu_dev_type) (__major & ~0xfff)) << 32));
270 }
271
272 char *canonicalize_file_name (const char *name) __attribute__((weak));
canonicalize_file_name(const char * name)273 char *canonicalize_file_name (const char *name) {
274 // Although many C libraries allocate resolved_name in realpath() if it is NULL,
275 // this behaviour is implementation-defined (POSIX) and not implemented in uclibc.
276 char * resolved_name = malloc(PATH_MAX);
277 if (!resolved_name) return NULL;
278 if (!realpath(name, resolved_name)) {
279 free(resolved_name);
280 return NULL;
281 }
282 return resolved_name;
283 }
284
285 int getloadavg(double loadavg[], int nelem) __attribute__((weak));
getloadavg(double loadavg[],int nelem)286 int getloadavg(double loadavg[], int nelem) {
287 klee_warning("ignoring (-1 result)");
288 return -1;
289 }
290
291 pid_t wait(int *status) __attribute__((weak));
wait(int * status)292 pid_t wait(int *status) {
293 klee_warning("ignoring (ECHILD)");
294 errno = ECHILD;
295 return -1;
296 }
297
298 pid_t wait3(int *status, int options, struct rusage *rusage) __attribute__((weak));
wait3(int * status,int options,struct rusage * rusage)299 pid_t wait3(int *status, int options, struct rusage *rusage) {
300 klee_warning("ignoring (ECHILD)");
301 errno = ECHILD;
302 return -1;
303 }
304
305 pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage) __attribute__((weak));
wait4(pid_t pid,int * status,int options,struct rusage * rusage)306 pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage) {
307 klee_warning("ignoring (ECHILD)");
308 errno = ECHILD;
309 return -1;
310 }
311
312 pid_t waitpid(pid_t pid, int *status, int options) __attribute__((weak));
waitpid(pid_t pid,int * status,int options)313 pid_t waitpid(pid_t pid, int *status, int options) {
314 klee_warning("ignoring (ECHILD)");
315 errno = ECHILD;
316 return -1;
317 }
318
319 pid_t waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options) __attribute__((weak));
waitid(idtype_t idtype,id_t id,siginfo_t * infop,int options)320 pid_t waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options) {
321 klee_warning("ignoring (ECHILD)");
322 errno = ECHILD;
323 return -1;
324 }
325
326 /* ACL */
327
328 /* FIXME: We need autoconf magic for this. */
329
330 #ifdef HAVE_SYS_ACL_H
331
332 #include <sys/acl.h>
333
334 int acl_delete_def_file(const char *path_p) __attribute__((weak));
acl_delete_def_file(const char * path_p)335 int acl_delete_def_file(const char *path_p) {
336 klee_warning("ignoring (EPERM)");
337 errno = EPERM;
338 return -1;
339 }
340
341 int acl_extended_file(const char path_p) __attribute__((weak));
acl_extended_file(const char path_p)342 int acl_extended_file(const char path_p) {
343 klee_warning("ignoring (ENOENT)");
344 errno = ENOENT;
345 return -1;
346 }
347
348 int acl_entries(acl_t acl) __attribute__((weak));
acl_entries(acl_t acl)349 int acl_entries(acl_t acl) {
350 klee_warning("ignoring (EINVAL)");
351 errno = EINVAL;
352 return -1;
353 }
354
355 acl_t acl_from_mode(mode_t mode) __attribute__((weak));
acl_from_mode(mode_t mode)356 acl_t acl_from_mode(mode_t mode) {
357 klee_warning("ignoring (ENOMEM)");
358 errno = ENOMEM;
359 return NULL;
360 }
361
362 acl_t acl_get_fd(int fd) __attribute__((weak));
acl_get_fd(int fd)363 acl_t acl_get_fd(int fd) {
364 klee_warning("ignoring (ENOMEM)");
365 errno = ENOMEM;
366 return NULL;
367 }
368
369 acl_t acl_get_file(const char *pathname, acl_type_t type) __attribute__((weak));
acl_get_file(const char * pathname,acl_type_t type)370 acl_t acl_get_file(const char *pathname, acl_type_t type) {
371 klee_warning("ignoring (ENONMEM)");
372 errno = ENOMEM;
373 return NULL;
374 }
375
376 int acl_set_fd(int fd, acl_t acl) __attribute__((weak));
acl_set_fd(int fd,acl_t acl)377 int acl_set_fd(int fd, acl_t acl) {
378 klee_warning("ignoring (EPERM)");
379 errno = EPERM;
380 return -1;
381 }
382
383 int acl_set_file(const char *path_p, acl_type_t type, acl_t acl) __attribute__((weak));
acl_set_file(const char * path_p,acl_type_t type,acl_t acl)384 int acl_set_file(const char *path_p, acl_type_t type, acl_t acl) {
385 klee_warning("ignoring (EPERM)");
386 errno = EPERM;
387 return -1;
388 }
389
390 int acl_free(void *obj_p) __attribute__((weak));
acl_free(void * obj_p)391 int acl_free(void *obj_p) {
392 klee_warning("ignoring (EINVAL)");
393 errno = EINVAL;
394 return -1;
395 }
396
397 #endif
398
399 int mount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, const void *data) __attribute__((weak));
mount(const char * source,const char * target,const char * filesystemtype,unsigned long mountflags,const void * data)400 int mount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, const void *data) {
401 klee_warning("ignoring (EPERM)");
402 errno = EPERM;
403 return -1;
404 }
405
406 int umount(const char *target) __attribute__((weak));
umount(const char * target)407 int umount(const char *target) {
408 klee_warning("ignoring (EPERM)");
409 errno = EPERM;
410 return -1;
411 }
412
413 int umount2(const char *target, int flags) __attribute__((weak));
umount2(const char * target,int flags)414 int umount2(const char *target, int flags) {
415 klee_warning("ignoring (EPERM)");
416 errno = EPERM;
417 return -1;
418 }
419
420 #ifndef __FreeBSD__
421 int swapon(const char *path, int swapflags) __attribute__((weak));
swapon(const char * path,int swapflags)422 int swapon(const char *path, int swapflags) {
423 #else
424 int swapon(const char *path)__attribute__((weak));
425 int swapon(const char *path)
426 {
427 #endif
428 klee_warning("ignoring (EPERM)");
429 errno = EPERM;
430 return -1;
431 }
432
433 int swapoff(const char *path) __attribute__((weak));
434 int swapoff(const char *path) {
435 klee_warning("ignoring (EPERM)");
436 errno = EPERM;
437 return -1;
438 }
439
440 int setgid(gid_t gid) __attribute__((weak));
441 int setgid(gid_t gid) {
442 klee_warning("silently ignoring (returning 0)");
443 return 0;
444 }
445
446 #ifndef __FreeBSD__
447 int setgroups(size_t size, const gid_t *list) __attribute__((weak));
448 int setgroups(size_t size, const gid_t *list) {
449 #else
450 int setgroups(int size, const gid_t *list) __attribute__((weak));
451 int setgroups(int size, const gid_t *list) {
452 #endif
453 klee_warning("ignoring (EPERM)");
454 errno = EPERM;
455 return -1;
456 }
457
458 #ifndef __FreeBSD__
459 int sethostname(const char *name, size_t len) __attribute__((weak));
460 int sethostname(const char *name, size_t len) {
461 #else
462 int sethostname(const char *name, int len) __attribute__((weak));
463 int sethostname(const char *name, int len) {
464 #endif
465 klee_warning("ignoring (EPERM)");
466 errno = EPERM;
467 return -1;
468 }
469
470 int setpgid(pid_t pid, pid_t pgid) __attribute__((weak));
471 int setpgid(pid_t pid, pid_t pgid) {
472 klee_warning("ignoring (EPERM)");
473 errno = EPERM;
474 return -1;
475 }
476
477 #ifndef __FreeBSD__
478 int setpgrp(void) __attribute__((weak));
479 int setpgrp(void) {
480 #else
481 int setpgrp(pid_t a, pid_t b) __attribute__((weak));
482 int setpgrp(pid_t a, pid_t b) {
483 #endif
484 klee_warning("ignoring (EPERM)");
485 errno = EPERM;
486 return -1;
487 }
488
489 #ifndef __FreeBSD__
490 int setpriority(__priority_which_t which, id_t who, int prio) __attribute__((weak));
491 int setpriority(__priority_which_t which, id_t who, int prio) {
492 #else
493 int setpriority(int which, int who, int prio) __attribute__((weak));
494 int setpriority(int which, int who, int prio) {
495 #endif
496 klee_warning("ignoring (EPERM)");
497 errno = EPERM;
498 return -1;
499 }
500
501 int setresgid(gid_t rgid, gid_t egid, gid_t sgid) __attribute__((weak));
502 int setresgid(gid_t rgid, gid_t egid, gid_t sgid) {
503 klee_warning("ignoring (EPERM)");
504 errno = EPERM;
505 return -1;
506 }
507
508 int setresuid(uid_t ruid, uid_t euid, uid_t suid) __attribute__((weak));
509 int setresuid(uid_t ruid, uid_t euid, uid_t suid) {
510 klee_warning("ignoring (EPERM)");
511 errno = EPERM;
512 return -1;
513 }
514
515 #ifndef __FreeBSD__
516 int setrlimit(__rlimit_resource_t resource, const struct rlimit *rlim) __attribute__((weak));
517 int setrlimit(__rlimit_resource_t resource, const struct rlimit *rlim) {
518 #else
519 int setrlimit(int resource, const struct rlimit *rlp) __attribute__((weak));
520 int setrlimit(int resource, const struct rlimit *rlp) {
521 #endif
522 klee_warning("ignoring (EPERM)");
523 errno = EPERM;
524 return -1;
525 }
526
527 #ifndef __FreeBSD__
528 int setrlimit64(__rlimit_resource_t resource, const struct rlimit64 *rlim) __attribute__((weak));
529 int setrlimit64(__rlimit_resource_t resource, const struct rlimit64 *rlim) {
530 klee_warning("ignoring (EPERM)");
531 errno = EPERM;
532 return -1;
533 }
534 #endif
535
536 pid_t setsid(void) __attribute__((weak));
537 pid_t setsid(void) {
538 klee_warning("ignoring (EPERM)");
539 errno = EPERM;
540 return -1;
541 }
542
543 int settimeofday(const struct timeval *tv, const struct timezone *tz) __attribute__((weak));
544 int settimeofday(const struct timeval *tv, const struct timezone *tz) {
545 klee_warning("ignoring (EPERM)");
546 errno = EPERM;
547 return -1;
548 }
549
550 int setuid(uid_t uid) __attribute__((weak));
551 int setuid(uid_t uid) {
552 klee_warning("silently ignoring (returning 0)");
553 return 0;
554 }
555
556 int reboot(int flag) __attribute__((weak));
557 int reboot(int flag) {
558 klee_warning("ignoring (EPERM)");
559 errno = EPERM;
560 return -1;
561 }
562
563 int mlock(const void *addr, size_t len) __attribute__((weak));
564 int mlock(const void *addr, size_t len) {
565 klee_warning("ignoring (EPERM)");
566 errno = EPERM;
567 return -1;
568 }
569
570 int munlock(const void *addr, size_t len) __attribute__((weak));
571 int munlock(const void *addr, size_t len) {
572 klee_warning("ignoring (EPERM)");
573 errno = EPERM;
574 return -1;
575 }
576
577 int pause(void) __attribute__((weak));
578 int pause(void) {
579 klee_warning("ignoring (EPERM)");
580 errno = EPERM;
581 return -1;
582 }
583
584 ssize_t readahead(int fd, off64_t *offset, size_t count) __attribute__((weak));
585 ssize_t readahead(int fd, off64_t *offset, size_t count) {
586 klee_warning("ignoring (EPERM)");
587 errno = EPERM;
588 return -1;
589 }
590
591 void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) __attribute__((weak));
592 void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) {
593 klee_warning("ignoring (EPERM)");
594 errno = EPERM;
595 return (void*) -1;
596 }
597
598 void *mmap64(void *start, size_t length, int prot, int flags, int fd, off64_t offset) __attribute__((weak));
599 void *mmap64(void *start, size_t length, int prot, int flags, int fd, off64_t offset) {
600 klee_warning("ignoring (EPERM)");
601 errno = EPERM;
602 return (void*) -1;
603 }
604
605 int munmap(void*start, size_t length) __attribute__((weak));
606 int munmap(void*start, size_t length) {
607 klee_warning("ignoring (EPERM)");
608 errno = EPERM;
609 return -1;
610 }
611