Skip to content

Commit fa89b6a

Browse files
authored
Merge pull request #5666 from tautschnig/_chk
C library: *_chk implementations must handle -1 (unknown) as dest size
2 parents c9c3ca6 + 3e0a45a commit fa89b6a

File tree

3 files changed

+28
-22
lines changed

3 files changed

+28
-22
lines changed

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

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

44
int main()
55
{
6-
strcpy();
7-
assert(0);
6+
char d[4];
7+
char *r = strcpy(d, "abc");
8+
assert(r == d);
9+
assert(strlen(d) == 3);
810
return 0;
911
}

regression/cbmc-library/strcpy-01/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--pointer-check --bounds-check
44
^EXIT=0$

src/ansi-c/library/string.c

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ __CPROVER_HIDE:;
1111
__CPROVER_buffer_size(dst) > __CPROVER_zero_string_length(src),
1212
"strcpy buffer overflow");
1313
__CPROVER_precondition(
14-
__CPROVER_buffer_size(dst) == s, "builtin object size");
14+
s == ~(__CPROVER_size_t)0 || __CPROVER_buffer_size(dst) == s,
15+
"builtin object size");
1516
dst[__CPROVER_zero_string_length(src)] = 0;
1617
__CPROVER_is_zero_string(dst) = 1;
1718
__CPROVER_zero_string_length(dst) = __CPROVER_zero_string_length(src);
1819
#else
1920
__CPROVER_precondition(
20-
__CPROVER_POINTER_OBJECT(dst) != __CPROVER_POINTER_OBJECT(src) ||
21-
(src >= dst + s) || (dst >= src + s),
21+
__CPROVER_POINTER_OBJECT(dst) != __CPROVER_POINTER_OBJECT(src),
2222
"strcpy src/dst overlap");
2323
__CPROVER_size_t i = 0;
2424
char ch;
@@ -45,7 +45,8 @@ __CPROVER_HIDE:;
4545
__CPROVER_precondition(
4646
__CPROVER_is_zero_string(src), "strcat zero-termination of 2nd argument");
4747
__CPROVER_precondition(
48-
__CPROVER_buffer_size(dst) == s, "builtin object size");
48+
s == ~(__CPROVER_size_t)0 || __CPROVER_buffer_size(dst) == s,
49+
"builtin object size");
4950
new_size =
5051
__CPROVER_zero_string_length(dst) + __CPROVER_zero_string_length(src);
5152
__CPROVER_assert(
@@ -58,8 +59,7 @@ __CPROVER_HIDE:;
5859
__CPROVER_zero_string_length(dst) = new_size;
5960
#else
6061
__CPROVER_precondition(
61-
__CPROVER_POINTER_OBJECT(dst) != __CPROVER_POINTER_OBJECT(src) ||
62-
(src >= dst + s) || (dst >= src + s),
62+
__CPROVER_POINTER_OBJECT(dst) != __CPROVER_POINTER_OBJECT(src),
6363
"strcat src/dst overlap");
6464
__CPROVER_size_t i = 0;
6565
while(dst[i] != 0)
@@ -91,7 +91,8 @@ __CPROVER_HIDE:;
9191
__CPROVER_is_zero_string(src) || __CPROVER_buffer_size(src) >= n,
9292
"strncat zero-termination of 2nd argument");
9393
__CPROVER_precondition(
94-
__CPROVER_buffer_size(dst) == s, "builtin object size");
94+
s == ~(__CPROVER_size_t)0 || __CPROVER_buffer_size(dst) == s,
95+
"builtin object size");
9596
additional = (n < __CPROVER_zero_string_length(src))
9697
? n
9798
: __CPROVER_zero_string_length(src);
@@ -107,8 +108,7 @@ __CPROVER_HIDE:;
107108
__CPROVER_zero_string_length(dst) = new_size;
108109
#else
109110
__CPROVER_precondition(
110-
__CPROVER_POINTER_OBJECT(dst) != __CPROVER_POINTER_OBJECT(src) ||
111-
(src >= dst + s) || (dst >= src + s),
111+
__CPROVER_POINTER_OBJECT(dst) != __CPROVER_POINTER_OBJECT(src),
112112
"strncat src/dst overlap");
113113

114114
__CPROVER_size_t i = 0;
@@ -220,7 +220,8 @@ __CPROVER_HIDE:;
220220
__CPROVER_precondition(
221221
__CPROVER_buffer_size(dst) >= n, "strncpy buffer overflow");
222222
__CPROVER_precondition(
223-
__CPROVER_buffer_size(dst) == object_size, "strncpy object size");
223+
object_size == ~(size_t)0 || __CPROVER_buffer_size(dst) == object_size,
224+
"strncpy object size");
224225
__CPROVER_is_zero_string(dst) = __CPROVER_zero_string_length(src) < n;
225226
__CPROVER_zero_string_length(dst) = __CPROVER_zero_string_length(src);
226227
#else
@@ -660,7 +661,8 @@ void *__builtin___memcpy_chk(void *dst, const void *src, __CPROVER_size_t n, __C
660661
__CPROVER_precondition(
661662
__CPROVER_buffer_size(dst) >= n, "memcpy buffer overflow");
662663
__CPROVER_precondition(
663-
__CPROVER_buffer_size(dst) == s, "builtin object size");
664+
size == ~(__CPROVER_size_t)0 || __CPROVER_buffer_size(dst) == size,
665+
"builtin object size");
664666
// for(size_t i=0; i<n ; i++) dst[i]=src[i];
665667
if(__CPROVER_is_zero_string(src) && n > __CPROVER_zero_string_length(src))
666668
{
@@ -782,12 +784,13 @@ void *__builtin_memset(void *s, int c, __CPROVER_size_t n)
782784

783785
void *__builtin___memset_chk(void *s, int c, __CPROVER_size_t n, __CPROVER_size_t size)
784786
{
785-
__CPROVER_HIDE:;
786-
#ifdef __CPROVER_STRING_ABSTRACTION
787+
__CPROVER_HIDE:;
788+
#ifdef __CPROVER_STRING_ABSTRACTION
787789
__CPROVER_precondition(__CPROVER_buffer_size(s)>=n,
788790
"memset buffer overflow");
789-
__CPROVER_precondition(__CPROVER_buffer_size(s)==size,
790-
"builtin object size");
791+
__CPROVER_precondition(
792+
size == ~(__CPROVER_size_t)0 || __CPROVER_buffer_size(s) == size,
793+
"builtin object size");
791794
// for(size_t i=0; i<n ; i++) s[i]=c;
792795
if(__CPROVER_is_zero_string(s) &&
793796
n > __CPROVER_zero_string_length(s))
@@ -801,7 +804,7 @@ void *__builtin___memset_chk(void *s, int c, __CPROVER_size_t n, __CPROVER_size_
801804
}
802805
else
803806
__CPROVER_is_zero_string(s)=0;
804-
#else
807+
#else
805808
__CPROVER_precondition(__CPROVER_w_ok(s, n),
806809
"memset destination region writeable");
807810
(void)size;
@@ -814,7 +817,7 @@ void *__builtin___memset_chk(void *s, int c, __CPROVER_size_t n, __CPROVER_size_
814817
__CPROVER_array_set(s_n, (unsigned char)c);
815818
__CPROVER_array_replace((unsigned char *)s, s_n);
816819
}
817-
#endif
820+
#endif
818821
return s;
819822
}
820823

@@ -873,8 +876,9 @@ void *__builtin___memmove_chk(void *dest, const void *src, size_t n, __CPROVER_s
873876
#ifdef __CPROVER_STRING_ABSTRACTION
874877
__CPROVER_precondition(__CPROVER_buffer_size(src)>=n,
875878
"memmove buffer overflow");
876-
__CPROVER_precondition(__CPROVER_buffer_size(dest)==size,
877-
"builtin object size");
879+
__CPROVER_precondition(
880+
size == ~(__CPROVER_size_t)0 || __CPROVER_buffer_size(dest) == size,
881+
"builtin object size");
878882
// dst = src (with overlap allowed)
879883
if(__CPROVER_is_zero_string(src) &&
880884
n > __CPROVER_zero_string_length(src))

0 commit comments

Comments
 (0)