Skip to content

Commit 7ce478a

Browse files
committed
ssh: fixing unsigned overflow leading to heap overflow
cf GHSL-2020-051
1 parent 3bbb0cd commit 7ce478a

File tree

1 file changed

+33
-31
lines changed

1 file changed

+33
-31
lines changed

‎src/lib/protocols/ssh.c‎

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ static void ndpi_int_ssh_add_connection(struct ndpi_detection_module_struct
9595

9696
static u_int16_t concat_hash_string(struct ndpi_packet_struct *packet,
9797
char *buf, u_int8_t client_hash) {
98-
u_int16_t offset = 22, buf_out_len = 0;
98+
u_int32_t offset = 22, buf_out_len = 0;
9999
if(offset+sizeof(u_int32_t) >= packet->payload_packet_len)
100100
goto invalid_payload;
101101
u_int32_t len = ntohl(*(u_int32_t*)&packet->payload[offset]);
@@ -114,113 +114,115 @@ static u_int16_t concat_hash_string(struct ndpi_packet_struct *packet,
114114
goto invalid_payload;
115115
/* ssh.server_host_key_algorithms [None] */
116116
len = ntohl(*(u_int32_t*)&packet->payload[offset]);
117+
if (len > UINT32_MAX - 4 - offset)
118+
goto invalid_payload;
117119
offset += 4 + len;
118120

119121
if(offset+sizeof(u_int32_t) >= packet->payload_packet_len)
120122
goto invalid_payload;
121123
/* ssh.encryption_algorithms_client_to_server [C] */
122124
len = ntohl(*(u_int32_t*)&packet->payload[offset]);
123125

126+
offset += 4;
124127
if(client_hash) {
125-
offset += 4;
126-
127128
if((offset >= packet->payload_packet_len) || (len >= packet->payload_packet_len-offset-1))
128129
goto invalid_payload;
129130

130131
strncpy(&buf[buf_out_len], (const char *)&packet->payload[offset], len);
131132
buf_out_len += len;
132133
buf[buf_out_len++] = ';';
133-
offset += len;
134-
} else
135-
offset += 4 + len;
134+
}
135+
if (len > UINT32_MAX - offset)
136+
goto invalid_payload;
137+
offset += len;
136138

137139
if(offset+sizeof(u_int32_t) >= packet->payload_packet_len)
138140
goto invalid_payload;
139141
/* ssh.encryption_algorithms_server_to_client [S] */
140142
len = ntohl(*(u_int32_t*)&packet->payload[offset]);
141143

144+
offset += 4;
142145
if(!client_hash) {
143-
offset += 4;
144-
145146
if((offset >= packet->payload_packet_len) || (len >= packet->payload_packet_len-offset-1))
146147
goto invalid_payload;
147148

148149
strncpy(&buf[buf_out_len], (const char *)&packet->payload[offset], len);
149150
buf_out_len += len;
150151
buf[buf_out_len++] = ';';
151-
offset += len;
152-
} else
153-
offset += 4 + len;
152+
}
153+
if (len > UINT32_MAX - offset)
154+
goto invalid_payload;
155+
offset += len;
154156

155157
if(offset+sizeof(u_int32_t) >= packet->payload_packet_len)
156158
goto invalid_payload;
157159
/* ssh.mac_algorithms_client_to_server [C] */
158160
len = ntohl(*(u_int32_t*)&packet->payload[offset]);
159161

162+
offset += 4;
160163
if(client_hash) {
161-
offset += 4;
162-
163164
if((offset >= packet->payload_packet_len) || (len >= packet->payload_packet_len-offset-1))
164165
goto invalid_payload;
165166

166167
strncpy(&buf[buf_out_len], (const char *)&packet->payload[offset], len);
167168
buf_out_len += len;
168169
buf[buf_out_len++] = ';';
169-
offset += len;
170-
} else
171-
offset += 4 + len;
170+
}
171+
if (len > UINT32_MAX - offset)
172+
goto invalid_payload;
173+
offset += len;
172174

173175
if(offset+sizeof(u_int32_t) >= packet->payload_packet_len)
174176
goto invalid_payload;
175177
/* ssh.mac_algorithms_server_to_client [S] */
176178
len = ntohl(*(u_int32_t*)&packet->payload[offset]);
177179

180+
offset += 4;
178181
if(!client_hash) {
179-
offset += 4;
180-
181182
if((offset >= packet->payload_packet_len) || (len >= packet->payload_packet_len-offset-1))
182183
goto invalid_payload;
183184

184185
strncpy(&buf[buf_out_len], (const char *)&packet->payload[offset], len);
185186
buf_out_len += len;
186187
buf[buf_out_len++] = ';';
187-
offset += len;
188-
} else
189-
offset += 4 + len;
188+
}
189+
if (len > UINT32_MAX - offset)
190+
goto invalid_payload;
191+
offset += len;
190192

191193
/* ssh.compression_algorithms_client_to_server [C] */
192194
if(offset+sizeof(u_int32_t) >= packet->payload_packet_len)
193195
goto invalid_payload;
194196
len = ntohl(*(u_int32_t*)&packet->payload[offset]);
195197

198+
offset += 4;
196199
if(client_hash) {
197-
offset += 4;
198-
199200
if((offset >= packet->payload_packet_len) || (len >= packet->payload_packet_len-offset-1))
200201
goto invalid_payload;
201202

202203
strncpy(&buf[buf_out_len], (const char *)&packet->payload[offset], len);
203204
buf_out_len += len;
204-
offset += len;
205-
} else
206-
offset += 4 + len;
205+
}
206+
if (len > UINT32_MAX - offset)
207+
goto invalid_payload;
208+
offset += len;
207209

208210
if(offset+sizeof(u_int32_t) >= packet->payload_packet_len)
209211
goto invalid_payload;
210212
/* ssh.compression_algorithms_server_to_client [S] */
211213
len = ntohl(*(u_int32_t*)&packet->payload[offset]);
212214

215+
offset += 4;
213216
if(!client_hash) {
214-
offset += 4;
215-
216217
if((offset >= packet->payload_packet_len) || (len >= packet->payload_packet_len-offset-1))
217218
goto invalid_payload;
218219

219220
strncpy(&buf[buf_out_len], (const char *)&packet->payload[offset], len);
220221
buf_out_len += len;
221-
offset += len;
222-
} else
223-
offset += 4 + len;
222+
}
223+
if (len > UINT32_MAX - offset)
224+
goto invalid_payload;
225+
offset += len;
224226

225227
/* ssh.languages_client_to_server [None] */
226228

0 commit comments

Comments
 (0)