[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Some gm2 -fanalyzer results
From: |
Gaius Mulley |
Subject: |
Some gm2 -fanalyzer results |
Date: |
Fri, 09 Apr 2021 18:02:58 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) |
Hello,
I thought I'd post an email about the gcc analyzer working with gm2.
Here are a few test runs - taken from the regression testsuite - a
number of these tests are from the GCC manual converted into Modula-2.
The flag -fanalyzer turns on all static analysis.
$ cat badlistfree.mod
MODULE badlistfree ;
FROM Storage IMPORT ALLOCATE, DEALLOCATE ;
TYPE
list = POINTER TO RECORD
value: CARDINAL ;
next : list ;
END ;
VAR
head: list ;
PROCEDURE badfree (l: list) ;
BEGIN
DISPOSE (l) ;
WHILE l^.next # NIL DO
l := l^.next ;
DISPOSE (l)
END
END badfree ;
BEGIN
NEW (head) ;
badfree (head) ;
END badlistfree.
$ gm2 -g -c -fanalyzer badlistfree.mod
badlistfree.mod: In function ‘badfree’:
badlistfree.mod:16:24: warning: use after ‘DISPOSE’ of ‘l’ [CWE-416]
[-Wanalyzer-use-after-free]
16 | WHILE l^.next # NIL DO
| ^~
‘badfree’: events 1-2
|
| 15 | DISPOSE (l) ;
| | ^~~~~~~~~~
| | |
| | (1) deallocated here
| 16 | WHILE l^.next # NIL DO
| | ~~
| | |
| | (2) use after ‘DISPOSE’ of ‘l’; deallocated
at (1)
|
$ cat disposenoalloc.mod
MODULE disposenoalloc ;
FROM Storage IMPORT ALLOCATE, DEALLOCATE ;
FROM SYSTEM IMPORT ADR ;
TYPE
list = POINTER TO RECORD
value: CARDINAL ;
next : list ;
END ;
VAR
head: list ;
BEGIN
head := ADR (head) ;
DISPOSE (head)
END disposenoalloc.
$ gm2 -g -c -fanalyzer disposenoalloc.mod
disposenoalloc.mod: In function ‘_M2_disposenoalloc_init’:
disposenoalloc.mod:16:4: warning: ‘DISPOSE’ of ‘head’ which points to memory
not on the heap [CWE-590] [-Wanalyzer-free-of-non-heap]
16 | DISPOSE (head)
| ^~~~~~~~~~~~~
‘_M2_disposenoalloc_init’: events 1-3
|
| 15 | head := ADR (head) ;
| | ^
| | |
| | (1) pointer is from here
| 16 | DISPOSE (head)
| | ~~~~~~~~~~~~~
| | | |
| | | (2) pointer is from here
| | (3) call to ‘DISPOSE’ here
|
$ cat testdoubledispose.mod
MODULE testdoubledispose ;
FROM Storage IMPORT ALLOCATE, DEALLOCATE ;
TYPE
list = POINTER TO RECORD
value: CARDINAL ;
next : list ;
END ;
VAR
head: list ;
BEGIN
NEW (head) ;
DISPOSE (head) ;
DISPOSE (head) ;
END testdoubledispose.
$ gm2 -g -c -fanalyzer testdoubledispose.mod
testdoubledispose.mod: In function ‘_M2_testdoubledispose_init’:
testdoubledispose.mod:15:4: warning: double-‘DISPOSE’ of ‘head’ [CWE-415]
[-Wanalyzer-double-free]
15 | DISPOSE (head) ;
| ^~~~~~~~~~~~~
‘_M2_testdoubledispose_init’: events 1-3
|
| 13 | NEW (head) ;
| | ^~~~~~~~~
| | |
| | (1) allocated here
| 14 | DISPOSE (head) ;
| | ~~~~~~~~~~~~~
| | |
| | (2) first ‘DISPOSE’ here
| 15 | DISPOSE (head) ;
| | ~~~~~~~~~~~~~
| | |
| | (3) second ‘DISPOSE’ here; first ‘DISPOSE’ was at (2)
|
$ cat testdoublefree.mod
MODULE testdoublefree ;
FROM libc IMPORT malloc, free ;
FROM SYSTEM IMPORT ADDRESS ;
VAR
a: ADDRESS ;
BEGIN
a := malloc (100) ;
free (a) ;
free (a)
END testdoublefree.$ gm2 -g -c -fanalyzer testdoublefree.mod
testdoublefree.mod: In function ‘_M2_testdoublefree_init’:
testdoublefree.mod:11:4: warning: double-‘free’ of ‘a’ [CWE-415]
[-Wanalyzer-double-free]
11 | free (a)
| ^~~~
‘_M2_testdoublefree_init’: events 1-3
|
| 9 | a := malloc (100) ;
| | ^~~~~~
| | |
| | (1) allocated here
| 10 | free (a) ;
| | ~~~~
| | |
| | (2) first ‘free’ here
| 11 | free (a)
| | ~~~~
| | |
| | (3) second ‘free’ here; first ‘free’ was at (2)
|
$ cat useafterdeallocate.mod
MODULE useafterdeallocate ;
FROM Storage IMPORT ALLOCATE, DEALLOCATE ;
TYPE
ptrType = POINTER TO RECORD
foo: CARDINAL ;
END ;
VAR
head: ptrType ;
BEGIN
NEW (head) ;
IF head # NIL
THEN
head^.foo := 1 ;
DISPOSE (head) ;
head^.foo := 2
END
END useafterdeallocate.
$ gm2 -g -c -fanalyzer useafterdeallocate.mod
useafterdeallocate.mod: In function ‘_M2_useafterdeallocate_init’:
useafterdeallocate.mod:18:17: warning: use after ‘DISPOSE’ of ‘head’ [CWE-416]
[-Wanalyzer-use-after-free]
18 | head^.foo := 2
| ^~
‘_M2_useafterdeallocate_init’: events 1-6
|
| 13 | NEW (head) ;
| | ^~~~~~~~~
| | |
| | (1) allocated here
| 14 | IF head # NIL
| 15 | THEN
| | ~~~~
| | |
| | (2) assuming ‘head’ is non-NULL
| | (3) following ‘false’ branch...
| 16 | head^.foo := 1 ;
| | ~
| | |
| | (4) ...to here
| 17 | DISPOSE (head) ;
| | ~~~~~~~~~~~~~
| | |
| | (5) deallocated here
| 18 | head^.foo := 2
| | ~~
| | |
| | (6) use after ‘DISPOSE’ of ‘_T30’; deallocated at
(5)
|
the analyzer will be enabled for gm2 - if the
gcc/m2/patches/gcc/trunk/{16,17,18}* are applied to the gcc git trunk
(gcc-11). Once I've run the testsuite on other languages I'll push
these patches upstream,
regards,
Gaius
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Some gm2 -fanalyzer results,
Gaius Mulley <=