Skip to content

Commit d0e7f39

Browse files
committed
C library/scanf: havoc all target objects
scanf may write to any of the objects behind the pointer-typed arguments.
1 parent 67d9b6e commit d0e7f39

File tree

3 files changed

+61
-11
lines changed

3 files changed

+61
-11
lines changed

regression/cbmc-library/scanf-01/main.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,20 @@
33

44
int main()
55
{
6-
scanf();
7-
assert(0);
6+
scanf(""); // parse nothing, must not result in any out-of-bounds access
7+
int x = 0;
8+
scanf("%d", &x);
9+
_Bool nondet;
10+
if(nondet)
11+
__CPROVER_assert(x == 0, "need not remain zero");
12+
else
13+
__CPROVER_assert(x != 0, "may remain zero");
14+
long int lx = 0;
15+
long long int llx = 0;
16+
scanf("%d, %ld, %lld", &x, &lx, &llx);
17+
if(nondet)
18+
__CPROVER_assert(lx + llx == 0, "need not remain zero");
19+
else
20+
__CPROVER_assert(lx + llx != 0, "may remain zero");
821
return 0;
922
}
Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--pointer-check --bounds-check
4-
^EXIT=0$
4+
\[main.assertion.1\] line 11 need not remain zero: FAILURE$
5+
\[main.assertion.2\] line 13 may remain zero: FAILURE$
6+
\[main.assertion.3\] line 18 need not remain zero: FAILURE$
7+
\[main.assertion.4\] line 20 may remain zero: FAILURE$
8+
^\*\* 4 of \d+ failed
9+
^VERIFICATION FAILED$
10+
^EXIT=10$
511
^SIGNAL=0$
6-
^VERIFICATION SUCCESSFUL$
712
--
813
^warning: ignoring

src/ansi-c/library/stdio.c

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,12 @@ int vfscanf(FILE *restrict stream, const char *restrict format, va_list arg)
983983
}
984984

985985
(void)*format;
986-
(void)arg;
986+
while((__CPROVER_size_t)__CPROVER_POINTER_OFFSET(arg) <
987+
__CPROVER_OBJECT_SIZE(arg))
988+
{
989+
void *a = va_arg(arg, void *);
990+
__CPROVER_havoc_object(a);
991+
}
987992

988993
#ifdef __CPROVER_CUSTOM_BITVECTOR_ANALYSIS
989994
__CPROVER_assert(__CPROVER_get_must(stream, "open"),
@@ -1025,7 +1030,12 @@ __CPROVER_HIDE:;
10251030
}
10261031

10271032
(void)*format;
1028-
(void)arg;
1033+
while((__CPROVER_size_t)__CPROVER_POINTER_OFFSET(arg) <
1034+
__CPROVER_OBJECT_SIZE(arg))
1035+
{
1036+
void *a = va_arg(arg, void *);
1037+
__CPROVER_havoc_object(a);
1038+
}
10291039

10301040
#ifdef __CPROVER_CUSTOM_BITVECTOR_ANALYSIS
10311041
__CPROVER_assert(
@@ -1069,7 +1079,12 @@ int __stdio_common_vfscanf(
10691079
}
10701080

10711081
(void)*format;
1072-
(void)args;
1082+
while((__CPROVER_size_t)__CPROVER_POINTER_OFFSET(args) <
1083+
__CPROVER_OBJECT_SIZE(args))
1084+
{
1085+
void *a = va_arg(args, void *);
1086+
__CPROVER_havoc_object(a);
1087+
}
10731088

10741089
# ifdef __CPROVER_CUSTOM_BITVECTOR_ANALYSIS
10751090
__CPROVER_assert(
@@ -1137,7 +1152,13 @@ int vsscanf(const char *restrict s, const char *restrict format, va_list arg)
11371152
int result=__VERIFIER_nondet_int();
11381153
(void)*s;
11391154
(void)*format;
1140-
(void)arg;
1155+
while((__CPROVER_size_t)__CPROVER_POINTER_OFFSET(arg) <
1156+
__CPROVER_OBJECT_SIZE(arg))
1157+
{
1158+
void *a = va_arg(arg, void *);
1159+
__CPROVER_havoc_object(a);
1160+
}
1161+
11411162
return result;
11421163
}
11431164

@@ -1164,7 +1185,13 @@ __CPROVER_HIDE:;
11641185
int result = __VERIFIER_nondet_int();
11651186
(void)*s;
11661187
(void)*format;
1167-
(void)arg;
1188+
while((__CPROVER_size_t)__CPROVER_POINTER_OFFSET(arg) <
1189+
__CPROVER_OBJECT_SIZE(arg))
1190+
{
1191+
void *a = va_arg(arg, void *);
1192+
__CPROVER_havoc_object(a);
1193+
}
1194+
11681195
return result;
11691196
}
11701197

@@ -1199,7 +1226,12 @@ int __stdio_common_vsscanf(
11991226

12001227
(void)*s;
12011228
(void)*format;
1202-
(void)args;
1229+
while((__CPROVER_size_t)__CPROVER_POINTER_OFFSET(args) <
1230+
__CPROVER_OBJECT_SIZE(args))
1231+
{
1232+
void *a = va_arg(args, void *);
1233+
__CPROVER_havoc_object(a);
1234+
}
12031235

12041236
return result;
12051237
}

0 commit comments

Comments
 (0)