From 99b4ea80b3fa10f62ed5c592738a976da998f9c8 Mon Sep 17 00:00:00 2001 From: "Felipe R. Monteiro" Date: Thu, 22 Jun 2023 20:42:36 +0000 Subject: [PATCH] Adds an over-approximation model for sysconf Signed-off-by: Felipe R. Monteiro --- regression/cbmc-library/sysconf-01/main.c | 11 ++++++ regression/cbmc-library/sysconf-01/test.desc | 9 +++++ src/ansi-c/library/unistd.c | 36 ++++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 regression/cbmc-library/sysconf-01/main.c create mode 100644 regression/cbmc-library/sysconf-01/test.desc diff --git a/regression/cbmc-library/sysconf-01/main.c b/regression/cbmc-library/sysconf-01/main.c new file mode 100644 index 000000000000..32c9f2df2c76 --- /dev/null +++ b/regression/cbmc-library/sysconf-01/main.c @@ -0,0 +1,11 @@ +#include +#include + +int main() +{ + errno = 0; + long result = sysconf(_SC_ARG_MAX); + __CPROVER_assert( + !(errno == EINVAL) || (result == -1), + "Non-deterministically set errno to EINVAL"); +} diff --git a/regression/cbmc-library/sysconf-01/test.desc b/regression/cbmc-library/sysconf-01/test.desc new file mode 100644 index 000000000000..fbd6a7454ad8 --- /dev/null +++ b/regression/cbmc-library/sysconf-01/test.desc @@ -0,0 +1,9 @@ +CORE +main.c + +^EXIT=0$ +^SIGNAL=0$ +^\[main.assertion.\d+\] .* Non-deterministically set errno to EINVAL: SUCCESS$ +^\*\* 0 of 1 failed +-- +^WARNING: no body for function sysconf diff --git a/src/ansi-c/library/unistd.c b/src/ansi-c/library/unistd.c index 8563c41f020a..2499042c1dd0 100644 --- a/src/ansi-c/library/unistd.c +++ b/src/ansi-c/library/unistd.c @@ -319,3 +319,39 @@ ret_type _read(int fildes, void *buf, size_type nbyte) __CPROVER_HIDE:; return read(fildes, buf, nbyte); } + +/* FUNCTION: sysconf */ + +#ifndef __CPROVER_ERRNO_H_INCLUDED +# include +# define __CPROVER_ERRNO_H_INCLUDED +#endif + +long __VERIFIER_nondet_long(void); +__CPROVER_bool __VERIFIER_nondet___CPROVER_bool(void); + +long sysconf(int name); + +// This overapproximation is based on the sysconf specification available at +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html. +long sysconf(int name) +{ +__CPROVER_HIDE:; + (void)name; + long retval = __VERIFIER_nondet_long(); + __CPROVER_assume(retval >= -1); + + // Spec states "On error, -1 is returned and errno is set to indicate + // the error (for example, EINVAL, indicating that name is invalid). + // If name corresponds to a maximum or minimum limit, and that + // limit is indeterminate, -1 is returned and errno is not changed." + if(retval == -1 && __VERIFIER_nondet___CPROVER_bool()) + { + // Spec only lists EINVAL as possible errors. + errno = EINVAL; + } + + // Spec states "some returned values may be huge; they are not suitable + // for allocating memory", so keeping this non-deterministic. + return retval; +}