-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathArithmeticTainted.java
More file actions
141 lines (125 loc) · 3.18 KB
/
ArithmeticTainted.java
File metadata and controls
141 lines (125 loc) · 3.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Semmle test case for CWE-190: Integer Overflow or Wraparound
// http://cwe.mitre.org/data/definitions/190.html
package test.cwe190.semmle.tests;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class ArithmeticTainted {
public void main(String[] args) {
BufferedReader readerBuffered;
InputStreamReader readerInputStream;
int data;
try {
readerInputStream = new InputStreamReader(System.in, "UTF-8");
readerBuffered = new BufferedReader(readerInputStream);
String stringNumber = readerBuffered.readLine();
if (stringNumber != null) {
data = Integer.parseInt(stringNumber.trim());
} else {
data = 0;
}
} catch (IOException exceptIO) {
// fail
data = 0;
}
{
// BAD: may overflow if input data is very large
int scaled = data + 10;
}
{
// BAD: guard and then bypass
if (data > Integer.MIN_VALUE) {
System.out.println("I'm guarded");
}
int output = data - 10;
}
{
// BAD: guard and use after both branches
if (data < Integer.MAX_VALUE) {
System.out.println("I'm guarded");
} else {
System.out.println("I'm not guarded");
}
int output = data + 1;
}
{
// GOOD: use a guard to ensure no overflows occur
int scaled;
if (data < Integer.MAX_VALUE / 10 && data > Integer.MIN_VALUE / 10)
scaled = data * 10;
else
scaled = Integer.MAX_VALUE;
}
{
Holder tainted = new Holder(1);
tainted.setData(data);
Holder safe = new Holder(1);
int herring = tainted.getData();
int ok = safe.getData();
// GOOD
int output_ok = ok + 1;
// BAD
int output = herring + 1;
}
{
// guard against underflow
if (data > Integer.MIN_VALUE) {
int stillTainted = data - 1;
// FALSE NEGATIVE: stillTainted could still be very large, even
// after
// it has had arithmetic done on it
int output = stillTainted + 100;
}
}
{
// GOOD: tainted int value is widened to type long, thus avoiding
// overflow
// (see binary numeric promotions in JLS 5.6.2)
long widened = data + 10L;
}
{
// BAD: tainted int value is widened to type long, but subsequently
// cast to narrower type int
int widenedThenNarrowed = (int) (data + 10L);
}
// The following test case has an arbitrary guard on hashcode
// because otherwise the return statement causes 'data' to be guarded
// in the subsequent test cases.
if (this.hashCode() > 0) {
// GOOD: guard and return if bad
if (data < Integer.MAX_VALUE) {
System.out.println("I'm guarded");
} else {
return;
}
int output = data + 1;
}
{
double x= Double.MAX_VALUE;
// OK: CWE-190 only pertains to integer arithmetic
double y = x * 2;
}
{
test(data);
test2(data);
test3(data);
test4(data);
}
}
public static void test(int data) {
// BAD: may overflow if input data is very large
data++;
}
public static void test2(int data) {
// BAD: may overflow if input data is very large
++data;
}
public static void test3(int data) {
// BAD: may underflow if input data is very small
data--;
}
public static void test4(int data) {
// BAD: may underflow if input data is very small
--data;
}
}