-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy path10865.diff
122 lines (113 loc) · 3.9 KB
/
10865.diff
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
commit 33a3ee6b39acd9799301ec6cc0069bc9e4b4428b
Author: Yifeng Sun <pkusunyifeng@gmail.com>
Date: Tue Nov 13 11:25:24 2018 -0800
odp-util: Add checking to prevent buffer overflow when parsing push_nsh
Previously, the buffer size of 'struct ofpbuf b' is less than the
size of 'char buf[512]', this could cause memory overflow of ofpbuf
when calling ofpbuf_put_hex. This patch fixes it.
Reported-at: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10865
Signed-off-by: Yifeng Sun <pkusunyifeng@gmail.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
diff --git a/lib/odp-util.c b/lib/odp-util.c
index 627baaa39..bb6669b37 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -2032,100 +2032,100 @@ static int
parse_odp_push_nsh_action(const char *s, struct ofpbuf *actions)
{
int n = 0;
int ret = 0;
uint32_t spi = 0;
uint8_t si = 255;
uint32_t cd;
struct ovs_key_nsh nsh;
uint8_t metadata[NSH_CTX_HDRS_MAX_LEN];
uint8_t md_size = 0;
if (!ovs_scan_len(s, &n, "push_nsh(")) {
ret = -EINVAL;
goto out;
}
/* The default is NSH_M_TYPE1 */
nsh.flags = 0;
nsh.ttl = 63;
nsh.mdtype = NSH_M_TYPE1;
nsh.np = NSH_P_ETHERNET;
nsh.path_hdr = nsh_spi_si_to_path_hdr(0, 255);
memset(nsh.context, 0, NSH_M_TYPE1_MDLEN);
for (;;) {
n += strspn(s + n, delimiters);
if (s[n] == ')') {
break;
}
if (ovs_scan_len(s, &n, "flags=%"SCNi8, &nsh.flags)) {
continue;
}
if (ovs_scan_len(s, &n, "ttl=%"SCNi8, &nsh.ttl)) {
continue;
}
if (ovs_scan_len(s, &n, "mdtype=%"SCNi8, &nsh.mdtype)) {
switch (nsh.mdtype) {
case NSH_M_TYPE1:
/* This is the default format. */;
break;
case NSH_M_TYPE2:
/* Length will be updated later. */
md_size = 0;
break;
default:
ret = -EINVAL;
goto out;
}
continue;
}
if (ovs_scan_len(s, &n, "np=%"SCNi8, &nsh.np)) {
continue;
}
if (ovs_scan_len(s, &n, "spi=0x%"SCNx32, &spi)) {
continue;
}
if (ovs_scan_len(s, &n, "si=%"SCNi8, &si)) {
continue;
}
if (nsh.mdtype == NSH_M_TYPE1) {
if (ovs_scan_len(s, &n, "c1=0x%"SCNx32, &cd)) {
nsh.context[0] = htonl(cd);
continue;
}
if (ovs_scan_len(s, &n, "c2=0x%"SCNx32, &cd)) {
nsh.context[1] = htonl(cd);
continue;
}
if (ovs_scan_len(s, &n, "c3=0x%"SCNx32, &cd)) {
nsh.context[2] = htonl(cd);
continue;
}
if (ovs_scan_len(s, &n, "c4=0x%"SCNx32, &cd)) {
nsh.context[3] = htonl(cd);
continue;
}
}
else if (nsh.mdtype == NSH_M_TYPE2) {
struct ofpbuf b;
char buf[512];
size_t mdlen, padding;
- if (ovs_scan_len(s, &n, "md2=0x%511[0-9a-fA-F]", buf)) {
- ofpbuf_use_stub(&b, metadata,
- NSH_CTX_HDRS_MAX_LEN);
+ if (ovs_scan_len(s, &n, "md2=0x%511[0-9a-fA-F]", buf)
+ && n/2 <= sizeof metadata) {
+ ofpbuf_use_stub(&b, metadata, sizeof metadata);
ofpbuf_put_hex(&b, buf, &mdlen);
/* Pad metadata to 4 bytes. */
padding = PAD_SIZE(mdlen, 4);
if (padding > 0) {
ofpbuf_push_zeros(&b, padding);
}
md_size = mdlen + padding;
ofpbuf_uninit(&b);
continue;
}
}
ret = -EINVAL;
goto out;
}