Skip to content

Commit b3bb9e4

Browse files
committed
Integer truncation false positive
Now you can do `char oops = 3458079` if you must
1 parent 2dd111c commit b3bb9e4

File tree

3 files changed

+152
-0
lines changed

3 files changed

+152
-0
lines changed

assets/semgrep_rules/blocklist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ https://semgrep.dev/r/terraform.aws.security.aws-elb-access-logs-not-enabled.aws
2323
https://github.com/0xdea/semgrep-rules/blob/main/c/mismatched-memory-management-cpp.yaml
2424
https://semgrep.dev/r/javascript.lang.security.audit.unsafe-formatstring.unsafe-formatstring
2525
https://semgrep.dev/r/yaml.github-actions.security.third-party-action-not-pinned-to-commit-sha.third-party-action-not-pinned-to-commit-sha
26+
https://github.com/0xdea/semgrep-rules/blob/main/c/integer-truncation.yaml
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Marco Ivaldi <[email protected]>
2+
3+
#include <stdio.h>
4+
5+
int assign_int(int int_var)
6+
{
7+
// ruleid: integer-truncation
8+
char char_var = int_var;
9+
short short_var;
10+
11+
// ruleid: integer-truncation
12+
short_var = int_var;
13+
}
14+
15+
int assign_long(long long_var)
16+
{
17+
short short_var;
18+
// ruleid: integer-truncation
19+
int int_var = long_var + 1;
20+
21+
// ruleid: integer-truncation
22+
short_var = long_var;
23+
}
24+
25+
int test_func()
26+
{
27+
int intPrimitive;
28+
short shortPrimitive;
29+
intPrimitive = (int)(~((int)0) ^ (1 << (sizeof(int)*8-1)));
30+
// ruleid: integer-truncation
31+
shortPrimitive = intPrimitive;
32+
printf("Int MAXINT: %d\nShort MAXINT: %d\n", intPrimitive, shortPrimitive);
33+
// ok: integer-truncation
34+
char c = 0x0;
35+
// ok: integer-truncation
36+
char cc = 127;
37+
printf("Chars: %c %c\n", c, cc);
38+
}
39+
40+
// ruleid: integer-truncation
41+
char func(void)
42+
{
43+
int a = 42;
44+
return a;
45+
}
46+
47+
int main()
48+
{
49+
printf("Hello, World!");
50+
return 0;
51+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
rules:
2+
- id: integer-truncation
3+
metadata:
4+
author: Marco Ivaldi <[email protected]>
5+
references:
6+
- https://cwe.mitre.org/data/definitions/197
7+
- https://cwe.mitre.org/data/definitions/681
8+
- https://g.co/kgs/PCHQjJ
9+
- https://github.com/struct/mms
10+
- https://github.com/0xdea/semgrep-rules/blob/main/c/integer-truncation.yaml
11+
confidence: MEDIUM
12+
license: MIT
13+
category: security
14+
subcategory:
15+
- audit
16+
source: https://github.com/brave/security-action/blob/main/assets/semgrep_rules/client/integer-truncation.yaml
17+
message: Truncation errors occur when a primitive is cast to a primitive of a smaller
18+
size and data is lost in the conversion. The value cannot be trusted and the
19+
application will be in an undefined state.
20+
severity: WARNING
21+
languages:
22+
- c
23+
- cpp
24+
patterns:
25+
- pattern-either:
26+
- pattern: (char $NARROW) = <... (short $LARGE) ...>
27+
- pattern: (char $NARROW) = <... (short int $LARGE) ...>
28+
- pattern: (char $NARROW) = <... (unsigned short $LARGE) ...>
29+
- pattern: (char $NARROW) = <... (unsigned short int $LARGE) ...>
30+
- pattern: (char $NARROW) = <... (int $LARGE) ...>
31+
- pattern: (char $NARROW) = <... (unsigned $LARGE) ...>
32+
- pattern: (char $NARROW) = <... (unsigned int $LARGE) ...>
33+
- pattern: (char $NARROW) = <... (long $LARGE) ...>
34+
- pattern: (char $NARROW) = <... (long int $LARGE) ...>
35+
- pattern: (char $NARROW) = <... (unsigned long $LARGE) ...>
36+
- pattern: (char $NARROW) = <... (unsigned long int $LARGE) ...>
37+
- pattern: |
38+
char $FUN(...)
39+
{
40+
...
41+
return (short $LARGE);
42+
}
43+
- pattern: |
44+
char $FUN(...)
45+
{
46+
...
47+
return (int $LARGE);
48+
}
49+
- pattern: |
50+
char $FUN(...)
51+
{
52+
...
53+
return (long $LARGE);
54+
}
55+
- pattern: (short $NARROW) = <... (unsigned short $LARGE) ...>
56+
- pattern: (short int $NARROW) = <... (unsigned short int $LARGE) ...>
57+
- pattern: (short $NARROW) = <... (int $LARGE) ...>
58+
- pattern: (short $NARROW) = <... (unsigned $LARGE) ...>
59+
- pattern: (short int $NARROW) = <... (unsigned int $LARGE) ...>
60+
- pattern: (short $NARROW) = <... (long $LARGE) ...>
61+
- pattern: (short int $NARROW) = <... (long int $LARGE) ...>
62+
- pattern: (short $NARROW) = <... (unsigned long $LARGE) ...>
63+
- pattern: (short int $NARROW) = <... (unsigned long int $LARGE) ...>
64+
- pattern: (unsigned short $NARROW) = <... (int $LARGE) ...>
65+
- pattern: (unsigned short $NARROW) = <... (unsigned $LARGE) ...>
66+
- pattern: (unsigned short int $NARROW) = <... (unsigned int $LARGE) ...>
67+
- pattern: (unsigned short $NARROW) = <... (long $LARGE) ...>
68+
- pattern: (unsigned short int $NARROW) = <... (long int $LARGE) ...>
69+
- pattern: (unsigned short $NARROW) = <... (unsigned long $LARGE) ...>
70+
- pattern: (unsigned short int $NARROW) = <... (unsigned long int $LARGE) ...>
71+
- pattern: |
72+
short $FUN(...)
73+
{
74+
...
75+
return (int $LARGE);
76+
}
77+
- pattern: |
78+
short $FUN(...)
79+
{
80+
...
81+
return (long $LARGE);
82+
}
83+
- pattern: (int $NARROW) = <... (unsigned $LARGE) ...>
84+
- pattern: (int $NARROW) = <... (unsigned int $LARGE) ...>
85+
- pattern: (int $NARROW) = <... (long $LARGE) ...>
86+
- pattern: (int $NARROW) = <... (long int $LARGE) ...>
87+
- pattern: (int $NARROW) = <... (unsigned long $LARGE) ...>
88+
- pattern: (int $NARROW) = <... (unsigned long int $LARGE) ...>
89+
- pattern: |
90+
int $FUN(...)
91+
{
92+
...
93+
return (long $LARGE);
94+
}
95+
- pattern: (long $NARROW) = <... (unsigned long $LARGE) ...>
96+
- pattern: (long int $NARROW) = <... (unsigned long int $LARGE) ...>
97+
# (Ben Caller) Prevent false positive with `char x = 0;` by using regex:
98+
- metavariable-regex:
99+
metavariable: $LARGE
100+
regex: '\A[^0-9]'

0 commit comments

Comments
 (0)