Skip to content

Commit b555f50

Browse files
authored
Merge pull request #1209 from geoffw0/gmtime
CPP: Add variants to PotentiallyDangerousFunction.ql
2 parents 6ba57fc + 7aee334 commit b555f50

5 files changed

Lines changed: 36 additions & 10 deletions

File tree

change-notes/1.21/analysis-cpp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
| Memory is never freed (`cpp/memory-never-freed`) | More correct results | Support added for more Microsoft-specific allocation functions, including `LocalAlloc`, `GlobalAlloc`, `HeapAlloc` and `CoTaskMemAlloc`. |
1919
| Resource not released in destructor (`cpp/resource-not-released-in-destructor`) | Fewer false positive results | Resource allocation and deallocation functions are now determined more accurately. |
2020
| Comparison result is always the same | Fewer false positive results | The range analysis library is now more conservative about floating point values being possibly `NaN` |
21+
| Use of potentially dangerous function | More correct results | Calls to `localtime`, `ctime` and `asctime` are now detected by this query. |
2122
| Wrong type of arguments to formatting function (`cpp/wrong-type-format-argument`) | More correct results and fewer false positive results | This query now more accurately identifies wide and non-wide string/character format arguments on different platforms. Platform detection has also been made more accurate for the purposes of this query. |
2223
| Wrong type of arguments to formatting function (`cpp/wrong-type-format-argument`) | Fewer false positive results | Non-standard uses of %L are now understood. |
2324

cpp/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.qhelp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
<overview>
66
<p>This rule finds calls to functions that are dangerous to
77
use. Currently, it checks for calls
8-
to <code>gets</code> and <code>gmtime</code>. See <strong>Related rules</strong>
9-
below for rules that identify other dangerous functions.</p>
8+
to <code>gets</code>, <code>gmtime</code>, <code>localtime</code>,
9+
<code>ctime</code> and <code>asctime</code>. See <strong>Related
10+
rules</strong> below for rules that identify other dangerous functions.</p>
1011

1112
<p>The <code>gets</code> function is one of the vulnerabilities exploited by the Internet Worm of 1988, one of the first computer worms to spread through the Internet. The <code>gets</code> function provides no way to limit the amount of data that is read and stored, so without prior knowledge of the input it is impossible to use it safely with any size of buffer.</p>
1213

13-
<p>The <code>gmtime</code> function fills data into a <code>tm</code>
14-
struct in shared memory and then returns a pointer to that struct. If
14+
<p>The time related functions such as <code>gmtime</code>
15+
fill data into a <code>tm</code> struct or <code>char</code> array in
16+
shared memory and then returns a pointer to that memory. If
1517
the function is called from multiple places in the same program, and
1618
especially if it is called from multiple threads in the same program,
1719
then the calls will overwrite each other's data.</p>
@@ -26,6 +28,11 @@ With <code>gmtime_r</code>, the application code manages allocation of
2628
the <code>tm</code> struct. That way, separate calls to the function
2729
can use their own storage.</p>
2830

31+
<p>Similarly replace calls to <code>localtime</code> with
32+
<code>localtime_r</code>, calls to <code>ctime</code> with
33+
<code>ctime_r</code> and calls to <code>asctime</code> with
34+
<code>asctime_r</code>.</p>
35+
2936
</recommendation>
3037
<example>
3138
<p>The following example checks the local time in two ways:</p>

cpp/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@
1212
import cpp
1313

1414
predicate potentiallyDangerousFunction(Function f, string message) {
15-
(
16-
f.getQualifiedName() = "gmtime" and
17-
message = "Call to gmtime is potentially dangerous"
15+
exists(string name | name = f.getQualifiedName() |
16+
(
17+
name = "gmtime" or
18+
name = "localtime" or
19+
name = "ctime" or
20+
name = "asctime"
21+
) and
22+
message = "Call to " + name + " is potentially dangerous"
1823
) or (
1924
f.getQualifiedName() = "gets" and
2025
message = "gets does not guard against buffer overflow"
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1-
| test.c:28:22:28:27 | call to gmtime | Call to gmtime is potentially dangerous |
2-
| test.c:39:2:39:5 | call to gets | gets does not guard against buffer overflow |
3-
| test.c:40:6:40:9 | call to gets | gets does not guard against buffer overflow |
1+
| test.c:31:22:31:27 | call to gmtime | Call to gmtime is potentially dangerous |
2+
| test.c:42:2:42:5 | call to gets | gets does not guard against buffer overflow |
3+
| test.c:43:6:43:9 | call to gets | gets does not guard against buffer overflow |
4+
| test.c:48:19:48:27 | call to localtime | Call to localtime is potentially dangerous |
5+
| test.c:49:22:49:26 | call to ctime | Call to ctime is potentially dangerous |
6+
| test.c:50:23:50:29 | call to asctime | Call to asctime is potentially dangerous |

cpp/ql/test/query-tests/Security/CWE/CWE-676/semmle/PotentiallyDangerousFunction/test.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ struct tm {
2121

2222
struct tm *gmtime(const time_t *timer);
2323
time_t time(time_t *timer);
24+
struct tm *localtime(const time_t *timer);
25+
char *ctime(const time_t *timer);
26+
char *asctime(const struct tm *timeptr);
2427

2528
// Code under test
2629

@@ -39,3 +42,10 @@ void testGets() {
3942
gets(buf1); // BAD: use of gets
4043
s = gets(buf2); // BAD: use of gets
4144
}
45+
46+
void testTime()
47+
{
48+
struct tm *now = localtime(time(NULL)); // BAD: localtime uses shared state
49+
char *time_string = ctime(time(NULL)); // BAD: localtime uses shared state
50+
char *time_string2 = asctime(now); // BAD: localtime uses shared state
51+
}

0 commit comments

Comments
 (0)