Skip to content

Commit 49aba25

Browse files
authored
Merge pull request github#16445 from geoffw0/qhelp4
C++: Improve qhelp for DoubleFree.
2 parents 59fb9cc + 53d4a10 commit 49aba25

File tree

5 files changed

+63
-4
lines changed

5 files changed

+63
-4
lines changed

cpp/ql/src/Critical/DoubleFree.qhelp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,32 @@ the program, or security vulnerabilities, by allowing an attacker to overwrite a
1414
</overview>
1515
<recommendation>
1616
<p>
17-
Ensure that all execution paths deallocate the allocated memory at most once. If possible, reassign
18-
the pointer to a null value after deallocating it. This will prevent double-free vulnerabilities since
19-
most deallocation functions will perform a null-pointer check before attempting to deallocate the memory.
17+
Ensure that all execution paths deallocate the allocated memory at most once. In complex cases it may
18+
help to reassign a pointer to a null value after deallocating it. This will prevent double-free vulnerabilities
19+
since most deallocation functions will perform a null-pointer check before attempting to deallocate memory.
2020
</p>
2121

2222
</recommendation>
23-
<example><sample src="DoubleFree.cpp" />
23+
<example>
24+
<p>
25+
In the following example, <code>buff</code> is allocated and then freed twice:
26+
</p>
27+
<sample src="DoubleFreeBad.cpp" />
28+
<p>
29+
Reviewing the code above, the issue can be fixed by simply deleting the additional call to
30+
<code>free(buff)</code>.
31+
</p>
32+
<sample src="DoubleFreeGood.cpp" />
33+
<p>
34+
In the next example, <code>task</code> may be deleted twice, if an exception occurs inside the <code>try</code>
35+
block after the first <code>delete</code>:
36+
</p>
37+
<sample src="DoubleFreeBad2.cpp" />
38+
<p>
39+
The problem can be solved by assigning a null value to the pointer after the first <code>delete</code>, as
40+
calling <code>delete</code> a second time on the null pointer is harmless.
41+
</p>
42+
<sample src="DoubleFreeGood2.cpp" />
2443
</example>
2544
<references>
2645

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
void g() {
2+
MyTask *task = nullptr;
3+
4+
try
5+
{
6+
task = new MyTask;
7+
8+
...
9+
10+
delete task;
11+
12+
...
13+
} catch (...) {
14+
delete task; // BAD: potential double-free
15+
}
16+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
int* f() {
2+
int *buff = malloc(SIZE*sizeof(int));
3+
do_stuff(buff);
4+
free(buff); // GOOD: buff is only freed once.
5+
int *new_buffer = malloc(SIZE*sizeof(int));
6+
return new_buffer;
7+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
void g() {
2+
MyTask *task = nullptr;
3+
4+
try
5+
{
6+
task = new MyTask;
7+
8+
...
9+
10+
delete task;
11+
task = nullptr;
12+
13+
...
14+
} catch (...) {
15+
delete task; // GOOD: harmless if task is NULL
16+
}
17+
}

0 commit comments

Comments
 (0)