Skip to content

Commit 5b1db44

Browse files
committed
Adds an over-approximation for syscall function
Signed-off-by: Felipe R. Monteiro <[email protected]>
1 parent f33b96a commit 5b1db44

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <sys/syscall.h>
2+
3+
#include <assert.h>
4+
#include <errno.h>
5+
#include <unistd.h>
6+
7+
int main()
8+
{
9+
long int rc;
10+
errno = 0;
11+
rc = syscall(SYS_chmod, "/etc/passwd", 0444);
12+
assert(!(rc != -1) || (errno == 0));
13+
14+
pid_t tid;
15+
// arithmetic overflow
16+
tid = syscall(SYS_gettid);
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE unix
2+
main.c
3+
--pointer-check --bounds-check --conversion-check
4+
^\[main.assertion.\d+\] line \d+ assertion !\(rc != -1\) || \(errno == 0\): SUCCESS$
5+
^\[main.overflow.\d+\] line \d+ arithmetic overflow on signed type conversion in \(pid\_t\)return\_value\_syscall: FAILURE$
6+
^\*\* 1 of \d+ failed .*$
7+
^VERIFICATION FAILED$
8+
^EXIT=10$
9+
^SIGNAL=0$
10+
--
11+
^\*\*\*\* WARNING: no body for function syscall

src/ansi-c/library/unistd.c

+39
Original file line numberDiff line numberDiff line change
@@ -385,3 +385,42 @@ __CPROVER_HIDE:;
385385
// Thus, modelling it as non-deterministic.
386386
return retval;
387387
}
388+
389+
/* FUNCTION: syscall */
390+
391+
#ifndef __CPROVER_ERRNO_H_INCLUDED
392+
# include <errno.h>
393+
# define __CPROVER_ERRNO_H_INCLUDED
394+
#endif
395+
396+
long int __VERIFIER_nondet_long_int(void);
397+
int __VERIFIER_nondet_int(void);
398+
399+
long int syscall(long int sysno, ...);
400+
401+
// This overapproximation is based on the syscall specification available at
402+
// https://man7.org/linux/man-pages/man2/syscall.2.html and
403+
// https://www.gnu.org/software/libc/manual/html_node/System-Calls.html.
404+
//
405+
// sysno is the system call number. The remaining arguments are the arguments
406+
// for the system call. Each kind of system call has a definite number of
407+
// arguments, from zero to five. If you code more arguments than the system
408+
// call takes, the extra ones to the right are ignored.
409+
long int syscall(long int sysno, ...)
410+
{
411+
__CPROVER_HIDE:;
412+
(void)sysno;
413+
long int retval = __VERIFIER_nondet_long_int();
414+
415+
if(retval == -1)
416+
{
417+
// We should keep errno as non-deterministic as possible, since this model
418+
// never takes into account any input.
419+
errno = __VERIFIER_nondet_int();
420+
}
421+
422+
// The return value is the return value from the system call, unless the
423+
// system call failed. This over-approximation doesn't take into account
424+
// any system call operation, so we leave the return value as non-det.
425+
return retval;
426+
}

0 commit comments

Comments
 (0)