Skip to content

Commit 1453345

Browse files
authored
Merge pull request #7365 from tautschnig/bugfixes/5570-unistd
C library: Avoid arithmetic overflow with pipe operations
2 parents dbe5557 + 06c95d6 commit 1453345

File tree

3 files changed

+30
-10
lines changed

3 files changed

+30
-10
lines changed
Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
1-
#include <assert.h>
1+
#include <limits.h>
22
#include <unistd.h>
33

4+
extern const __CPROVER_size_t SIZE;
5+
46
int main()
57
{
6-
write();
7-
assert(0);
8-
return 0;
8+
__CPROVER_assume(SIZE < SSIZE_MAX);
9+
10+
int fd;
11+
char ptr[SIZE];
12+
__CPROVER_size_t nbytes;
13+
14+
__CPROVER_assume(fd >= 0);
15+
__CPROVER_assume(nbytes < SIZE);
16+
17+
write(fd, ptr, nbytes);
918
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
KNOWNBUG
1+
CORE unix
22
main.c
3-
--pointer-check --bounds-check
3+
--pointer-check --bounds-check --conversion-check --unwind 1
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$

src/ansi-c/library/unistd.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ int pipe(int fildes[2])
6363
}
6464

6565
__CPROVER_atomic_begin();
66+
__CPROVER_assume(__CPROVER_pipe_offset >= 0);
6667
__CPROVER_assume(__CPROVER_pipe_offset%2==0);
6768
__CPROVER_assume(__CPROVER_pipe_offset<=(int)(__CPROVER_pipe_offset+__CPROVER_pipe_count));
6869
fildes[0]=__CPROVER_pipe_offset+__CPROVER_pipe_count;
@@ -106,6 +107,8 @@ int close(int fildes)
106107
if((fildes>=0 && fildes<=2) || fildes < __CPROVER_pipe_offset)
107108
return 0;
108109

110+
__CPROVER_assume(__CPROVER_pipe_offset >= 0);
111+
109112
int retval=-1;
110113
fildes-=__CPROVER_pipe_offset;
111114
if(fildes%2==1)
@@ -164,14 +167,18 @@ ret_type write(int fildes, const void *buf, size_type nbyte)
164167
return retval;
165168
}
166169

170+
__CPROVER_assume(__CPROVER_pipe_offset >= 0);
171+
167172
int retval=-1;
168173
fildes-=__CPROVER_pipe_offset;
169174
if(fildes%2==1)
170175
--fildes;
171176
__CPROVER_atomic_begin();
172-
if(!__CPROVER_pipes[fildes].widowed &&
173-
sizeof(__CPROVER_pipes[fildes].data) >=
174-
__CPROVER_pipes[fildes].next_avail+nbyte)
177+
if(
178+
!__CPROVER_pipes[fildes].widowed &&
179+
__CPROVER_pipes[fildes].next_avail >= 0 &&
180+
sizeof(__CPROVER_pipes[fildes].data) >=
181+
__CPROVER_pipes[fildes].next_avail + nbyte)
175182
{
176183
for(size_type i=0; i<nbyte; ++i)
177184
__CPROVER_pipes[fildes].data[i+__CPROVER_pipes[fildes].next_avail]=
@@ -262,12 +269,16 @@ ret_type read(int fildes, void *buf, size_type nbyte)
262269
return error ? -1 : nread;
263270
}
264271

272+
__CPROVER_assume(__CPROVER_pipe_offset >= 0);
273+
265274
int retval=0;
266275
fildes-=__CPROVER_pipe_offset;
267276
if(fildes%2==1)
268277
--fildes;
269278
__CPROVER_atomic_begin();
270-
if(!__CPROVER_pipes[fildes].widowed)
279+
if(
280+
!__CPROVER_pipes[fildes].widowed &&
281+
__CPROVER_pipes[fildes].next_unread >= 0)
271282
{
272283
for(size_type i=0; i<nbyte &&
273284
__CPROVER_pipes[fildes].next_unread <

0 commit comments

Comments
 (0)