/[packages]/updates/6/libssh2/current/SOURCES/libssh2-1.7.0-CVE-2019-3860.patch
ViewVC logotype

Contents of /updates/6/libssh2/current/SOURCES/libssh2-1.7.0-CVE-2019-3860.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1379152 - (show annotations) (download)
Wed Mar 20 09:53:24 2019 UTC (5 years, 1 month ago) by ns80
File size: 22135 byte(s)
- add patches for CVE-2019-385[5-9] and CVE-2019-386[0-3] (mga#24532)

1 commit ed0d9bd45e4d55cb3ca600c70fa26c6b7bf9bf05
2 Author: Michael Buckley <michael@panic.com>
3 Date: Wed Dec 5 10:35:19 2018 -0800
4
5 Add a required_size parameter to sftp_packet_require et. al. to require callers of these functions to handle packets that are too short.
6
7 diff --git a/src/sftp.c b/src/sftp.c
8 index 5316e7c..fd94d39 100644
9 --- a/src/sftp.c
10 +++ b/src/sftp.c
11 @@ -512,11 +512,15 @@ sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type,
12 static int
13 sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
14 uint32_t request_id, unsigned char **data,
15 - size_t *data_len)
16 + size_t *data_len, size_t required_size)
17 {
18 LIBSSH2_SESSION *session = sftp->channel->session;
19 int rc;
20
21 + if (data == NULL || data_len == NULL || required_size == 0) {
22 + return LIBSSH2_ERROR_BAD_USE;
23 + }
24 +
25 _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Requiring packet %d id %ld",
26 (int) packet_type, request_id);
27
28 @@ -524,6 +528,11 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
29 /* The right packet was available in the packet brigade */
30 _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Got %d",
31 (int) packet_type);
32 +
33 + if (*data_len < required_size) {
34 + return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
35 + }
36 +
37 return LIBSSH2_ERROR_NONE;
38 }
39
40 @@ -537,6 +546,11 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
41 /* The right packet was available in the packet brigade */
42 _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Got %d",
43 (int) packet_type);
44 +
45 + if (*data_len < required_size) {
46 + return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
47 + }
48 +
49 return LIBSSH2_ERROR_NONE;
50 }
51 }
52 @@ -552,11 +566,15 @@ static int
53 sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses,
54 const unsigned char *valid_responses,
55 uint32_t request_id, unsigned char **data,
56 - size_t *data_len)
57 + size_t *data_len, size_t required_size)
58 {
59 int i;
60 int rc;
61
62 + if (data == NULL || data_len == NULL || required_size == 0) {
63 + return LIBSSH2_ERROR_BAD_USE;
64 + }
65 +
66 /* If no timeout is active, start a new one */
67 if (sftp->requirev_start == 0)
68 sftp->requirev_start = time(NULL);
69 @@ -570,6 +588,11 @@ sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses,
70 * the timeout is not active
71 */
72 sftp->requirev_start = 0;
73 +
74 + if (*data_len < required_size) {
75 + return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
76 + }
77 +
78 return LIBSSH2_ERROR_NONE;
79 }
80 }
81 @@ -644,36 +667,65 @@ sftp_attr2bin(unsigned char *p, const LIBSSH2_SFTP_ATTRIBUTES * attrs)
82 /* sftp_bin2attr
83 */
84 static int
85 -sftp_bin2attr(LIBSSH2_SFTP_ATTRIBUTES * attrs, const unsigned char *p)
86 +sftp_bin2attr(LIBSSH2_SFTP_ATTRIBUTES * attrs, const unsigned char *p, size_t data_len)
87 {
88 const unsigned char *s = p;
89
90 - memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
91 - attrs->flags = _libssh2_ntohu32(s);
92 - s += 4;
93 + if (data_len >= 4) {
94 + memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
95 + attrs->flags = _libssh2_ntohu32(s);
96 + s += 4;
97 + data_len -= 4;
98 + }
99 + else {
100 + return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
101 + }
102
103 if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) {
104 - attrs->filesize = _libssh2_ntohu64(s);
105 - s += 8;
106 + if (data_len >= 8) {
107 + attrs->filesize = _libssh2_ntohu64(s);
108 + s += 8;
109 + data_len -= 8;
110 + }
111 + else {
112 + return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
113 + }
114 }
115
116 if (attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) {
117 - attrs->uid = _libssh2_ntohu32(s);
118 - s += 4;
119 - attrs->gid = _libssh2_ntohu32(s);
120 - s += 4;
121 + if (data_len >= 8) {
122 + attrs->uid = _libssh2_ntohu32(s);
123 + s += 4;
124 + attrs->gid = _libssh2_ntohu32(s);
125 + s += 4;
126 + data_len -= 8;
127 + }
128 + else {
129 + return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
130 + }
131 }
132
133 if (attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
134 - attrs->permissions = _libssh2_ntohu32(s);
135 - s += 4;
136 + if (data_len >= 4) {
137 + attrs->permissions = _libssh2_ntohu32(s);
138 + s += 4;
139 + data_len -= 4;
140 + }
141 + else {
142 + return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
143 + }
144 }
145
146 if (attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) {
147 - attrs->atime = _libssh2_ntohu32(s);
148 - s += 4;
149 - attrs->mtime = _libssh2_ntohu32(s);
150 - s += 4;
151 + if (data_len >= 8) {
152 + attrs->atime = _libssh2_ntohu32(s);
153 + s += 4;
154 + attrs->mtime = _libssh2_ntohu32(s);
155 + s += 4;
156 + }
157 + else {
158 + return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
159 + }
160 }
161
162 return (s - p);
163 @@ -843,18 +895,23 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
164 }
165
166 rc = sftp_packet_require(sftp_handle, SSH_FXP_VERSION,
167 - 0, &data, &data_len);
168 - if (rc == LIBSSH2_ERROR_EAGAIN)
169 + 0, &data, &data_len, 5);
170 + if (rc == LIBSSH2_ERROR_EAGAIN) {
171 + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
172 + "Would block receiving SSH_FXP_VERSION");
173 return NULL;
174 - else if (rc) {
175 - _libssh2_error(session, rc,
176 - "Timeout waiting for response from SFTP subsystem");
177 - goto sftp_init_error;
178 }
179 - if (data_len < 5) {
180 + else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
181 + if (data_len > 0) {
182 + LIBSSH2_FREE(session, data);
183 + }
184 _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
185 "Invalid SSH_FXP_VERSION response");
186 - LIBSSH2_FREE(session, data);
187 + goto sftp_init_error;
188 + }
189 + else if (rc) {
190 + _libssh2_error(session, rc,
191 + "Timeout waiting for response from SFTP subsystem");
192 goto sftp_init_error;
193 }
194
195 @@ -1120,12 +1177,20 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
196 { SSH_FXP_HANDLE, SSH_FXP_STATUS };
197 rc = sftp_packet_requirev(sftp, 2, fopen_responses,
198 sftp->open_request_id, &data,
199 - &data_len);
200 + &data_len, 1);
201 if (rc == LIBSSH2_ERROR_EAGAIN) {
202 _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
203 "Would block waiting for status message");
204 return NULL;
205 }
206 + else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
207 + if (data_len > 0) {
208 + LIBSSH2_FREE(session, data);
209 + }
210 + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
211 + "Response too small");
212 + return NULL;
213 + }
214 sftp->open_state = libssh2_NB_state_idle;
215 if (rc) {
216 _libssh2_error(session, rc, "Timeout waiting for status message");
217 @@ -1156,12 +1221,20 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
218 /* silly situation, but check for a HANDLE */
219 rc = sftp_packet_require(sftp, SSH_FXP_HANDLE,
220 sftp->open_request_id, &data,
221 - &data_len);
222 + &data_len, 10);
223 if(rc == LIBSSH2_ERROR_EAGAIN) {
224 /* go back to sent state and wait for something else */
225 sftp->open_state = libssh2_NB_state_sent;
226 return NULL;
227 }
228 + else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
229 + if (data_len > 0) {
230 + LIBSSH2_FREE(session, data);
231 + }
232 + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
233 + "Too small FXP_HANDLE");
234 + return NULL;
235 + }
236 else if(!rc)
237 /* we got the handle so this is not a bad situation */
238 badness = 0;
239 @@ -1488,15 +1561,21 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
240 }
241
242 rc = sftp_packet_requirev(sftp, 2, read_responses,
243 - chunk->request_id, &data, &data_len);
244 -
245 - if (rc==LIBSSH2_ERROR_EAGAIN && bytes_in_buffer != 0) {
246 + chunk->request_id, &data, &data_len, 9);
247 + if (rc == LIBSSH2_ERROR_EAGAIN && bytes_in_buffer != 0) {
248 /* do not return EAGAIN if we have already
249 * written data into the buffer */
250 return bytes_in_buffer;
251 }
252
253 - if (rc < 0) {
254 + if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
255 + if (data_len > 0) {
256 + LIBSSH2_FREE(session, data);
257 + }
258 + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
259 + "Response too small");
260 + }
261 + else if(rc < 0) {
262 sftp->read_state = libssh2_NB_state_sent2;
263 return rc;
264 }
265 @@ -1706,7 +1785,7 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
266 if (attrs)
267 memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
268
269 - s += sftp_bin2attr(attrs ? attrs : &attrs_dummy, s);
270 + s += sftp_bin2attr(attrs ? attrs : &attrs_dummy, s, 32);
271
272 handle->u.dir.next_name = (char *) s;
273 end:
274 @@ -1761,9 +1840,16 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
275
276 retcode = sftp_packet_requirev(sftp, 2, read_responses,
277 sftp->readdir_request_id, &data,
278 - &data_len);
279 + &data_len, 9);
280 if (retcode == LIBSSH2_ERROR_EAGAIN)
281 return retcode;
282 + else if (retcode == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
283 + if (data_len > 0) {
284 + LIBSSH2_FREE(session, data);
285 + }
286 + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
287 + "Status message too short");
288 + }
289 else if (retcode) {
290 sftp->readdir_state = libssh2_NB_state_idle;
291 return _libssh2_error(session, retcode,
292 @@ -1989,8 +2075,15 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
293
294 /* we check the packets in order */
295 rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
296 - chunk->request_id, &data, &data_len);
297 - if (rc < 0) {
298 + chunk->request_id, &data, &data_len, 9);
299 + if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
300 + if (data_len > 0) {
301 + LIBSSH2_FREE(session, data);
302 + }
303 + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
304 + "FXP write packet too short");
305 + }
306 + else if (rc < 0) {
307 if (rc == LIBSSH2_ERROR_EAGAIN)
308 sftp->write_state = libssh2_NB_state_sent;
309 return rc;
310 @@ -2132,10 +2225,18 @@ static int sftp_fsync(LIBSSH2_SFTP_HANDLE *handle)
311 }
312
313 rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
314 - sftp->fsync_request_id, &data, &data_len);
315 + sftp->fsync_request_id, &data, &data_len, 9);
316 if (rc == LIBSSH2_ERROR_EAGAIN) {
317 return rc;
318 - } else if (rc) {
319 + }
320 + else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
321 + if (data_len > 0) {
322 + LIBSSH2_FREE(session, data);
323 + }
324 + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
325 + "SFTP fsync packet too short");
326 + }
327 + else if (rc) {
328 sftp->fsync_state = libssh2_NB_state_idle;
329 return _libssh2_error(session, rc,
330 "Error waiting for FXP EXTENDED REPLY");
331 @@ -2235,9 +2336,16 @@ static int sftp_fstat(LIBSSH2_SFTP_HANDLE *handle,
332
333 rc = sftp_packet_requirev(sftp, 2, fstat_responses,
334 sftp->fstat_request_id, &data,
335 - &data_len);
336 + &data_len, 9);
337 if (rc == LIBSSH2_ERROR_EAGAIN)
338 return rc;
339 + else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
340 + if (data_len > 0) {
341 + LIBSSH2_FREE(session, data);
342 + }
343 + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
344 + "SFTP fstat packet too short");
345 + }
346 else if (rc) {
347 sftp->fstat_state = libssh2_NB_state_idle;
348 return _libssh2_error(session, rc,
349 @@ -2260,7 +2368,12 @@ static int sftp_fstat(LIBSSH2_SFTP_HANDLE *handle,
350 }
351 }
352
353 - sftp_bin2attr(attrs, data + 5);
354 + if (sftp_bin2attr(attrs, data + 5, data_len - 5) < 0) {
355 + LIBSSH2_FREE(session, data);
356 + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
357 + "Attributes too short in SFTP fstat");
358 + }
359 +
360 LIBSSH2_FREE(session, data);
361
362 return 0;
363 @@ -2437,11 +2550,19 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
364 if (handle->close_state == libssh2_NB_state_sent) {
365 rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
366 handle->close_request_id, &data,
367 - &data_len);
368 + &data_len, 9);
369 if (rc == LIBSSH2_ERROR_EAGAIN) {
370 return rc;
371 -
372 - } else if (rc) {
373 + }
374 + else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
375 + if (data_len > 0) {
376 + LIBSSH2_FREE(session, data);
377 + }
378 + data = NULL;
379 + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
380 + "Packet too short in FXP_CLOSE command");
381 + }
382 + else if (rc) {
383 _libssh2_error(session, rc,
384 "Error waiting for status message");
385 }
386 @@ -2555,10 +2676,17 @@ static int sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename,
387
388 rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
389 sftp->unlink_request_id, &data,
390 - &data_len);
391 + &data_len, 9);
392 if (rc == LIBSSH2_ERROR_EAGAIN) {
393 return rc;
394 }
395 + else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
396 + if (data_len > 0) {
397 + LIBSSH2_FREE(session, data);
398 + }
399 + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
400 + "SFTP unlink packet too short");
401 + }
402 else if (rc) {
403 sftp->unlink_state = libssh2_NB_state_idle;
404 return _libssh2_error(session, rc,
405 @@ -2666,10 +2794,18 @@ static int sftp_rename(LIBSSH2_SFTP *sftp, const char *source_filename,
406
407 rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
408 sftp->rename_request_id, &data,
409 - &data_len);
410 + &data_len, 9);
411 if (rc == LIBSSH2_ERROR_EAGAIN) {
412 return rc;
413 - } else if (rc) {
414 + }
415 + else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
416 + if (data_len > 0) {
417 + LIBSSH2_FREE(session, data);
418 + }
419 + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
420 + "SFTP rename packet too short");
421 + }
422 + else if (rc) {
423 sftp->rename_state = libssh2_NB_state_idle;
424 return _libssh2_error(session, rc,
425 "Error waiting for FXP STATUS");
426 @@ -2791,11 +2927,19 @@ static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st)
427 }
428
429 rc = sftp_packet_requirev(sftp, 2, responses, sftp->fstatvfs_request_id,
430 - &data, &data_len);
431 + &data, &data_len, 9);
432
433 if (rc == LIBSSH2_ERROR_EAGAIN) {
434 return rc;
435 - } else if (rc) {
436 + }
437 + else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
438 + if (data_len > 0) {
439 + LIBSSH2_FREE(session, data);
440 + }
441 + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
442 + "SFTP rename packet too short");
443 + }
444 + else if (rc) {
445 sftp->fstatvfs_state = libssh2_NB_state_idle;
446 return _libssh2_error(session, rc,
447 "Error waiting for FXP EXTENDED REPLY");
448 @@ -2918,10 +3062,18 @@ static int sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path,
449 }
450
451 rc = sftp_packet_requirev(sftp, 2, responses, sftp->statvfs_request_id,
452 - &data, &data_len);
453 + &data, &data_len, 9);
454 if (rc == LIBSSH2_ERROR_EAGAIN) {
455 return rc;
456 - } else if (rc) {
457 + }
458 + else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
459 + if (data_len > 0) {
460 + LIBSSH2_FREE(session, data);
461 + }
462 + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
463 + "SFTP fstat packet too short");
464 + }
465 + else if (rc) {
466 sftp->statvfs_state = libssh2_NB_state_idle;
467 return _libssh2_error(session, rc,
468 "Error waiting for FXP EXTENDED REPLY");
469 @@ -3048,10 +3200,18 @@ static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path,
470 }
471
472 rc = sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->mkdir_request_id,
473 - &data, &data_len);
474 + &data, &data_len, 9);
475 if (rc == LIBSSH2_ERROR_EAGAIN) {
476 return rc;
477 - } else if (rc) {
478 + }
479 + else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
480 + if (data_len > 0) {
481 + LIBSSH2_FREE(session, data);
482 + }
483 + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
484 + "SFTP mkdir packet too short");
485 + }
486 + else if (rc) {
487 sftp->mkdir_state = libssh2_NB_state_idle;
488 return _libssh2_error(session, rc,
489 "Error waiting for FXP STATUS");
490 @@ -3142,10 +3302,18 @@ static int sftp_rmdir(LIBSSH2_SFTP *sftp, const char *path,
491 }
492
493 rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
494 - sftp->rmdir_request_id, &data, &data_len);
495 + sftp->rmdir_request_id, &data, &data_len, 9);
496 if (rc == LIBSSH2_ERROR_EAGAIN) {
497 return rc;
498 - } else if (rc) {
499 + }
500 + else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
501 + if (data_len > 0) {
502 + LIBSSH2_FREE(session, data);
503 + }
504 + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
505 + "SFTP rmdir packet too short");
506 + }
507 + else if (rc) {
508 sftp->rmdir_state = libssh2_NB_state_idle;
509 return _libssh2_error(session, rc,
510 "Error waiting for FXP STATUS");
511 @@ -3255,9 +3423,16 @@ static int sftp_stat(LIBSSH2_SFTP *sftp, const char *path,
512 }
513
514 rc = sftp_packet_requirev(sftp, 2, stat_responses,
515 - sftp->stat_request_id, &data, &data_len);
516 + sftp->stat_request_id, &data, &data_len, 9);
517 if (rc == LIBSSH2_ERROR_EAGAIN)
518 return rc;
519 + else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
520 + if (data_len > 0) {
521 + LIBSSH2_FREE(session, data);
522 + }
523 + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
524 + "SFTP stat packet too short");
525 + }
526 else if (rc) {
527 sftp->stat_state = libssh2_NB_state_idle;
528 return _libssh2_error(session, rc,
529 @@ -3281,7 +3456,12 @@ static int sftp_stat(LIBSSH2_SFTP *sftp, const char *path,
530 }
531
532 memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
533 - sftp_bin2attr(attrs, data + 5);
534 + if (sftp_bin2attr(attrs, data + 5, data_len - 5) < 0) {
535 + LIBSSH2_FREE(session, data);
536 + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
537 + "Attributes too short in SFTP fstat");
538 + }
539 +
540 LIBSSH2_FREE(session, data);
541
542 return 0;
543 @@ -3386,9 +3566,16 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
544
545 retcode = sftp_packet_requirev(sftp, 2, link_responses,
546 sftp->symlink_request_id, &data,
547 - &data_len);
548 + &data_len, 9);
549 if (retcode == LIBSSH2_ERROR_EAGAIN)
550 return retcode;
551 + else if (retcode == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
552 + if (data_len > 0) {
553 + LIBSSH2_FREE(session, data);
554 + }
555 + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
556 + "SFTP symlink packet too short");
557 + }
558 else if (retcode) {
559 sftp->symlink_state = libssh2_NB_state_idle;
560 return _libssh2_error(session, retcode,
561 @@ -3418,6 +3605,14 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
562 "no name entries");
563 }
564
565 + if (data_len < 13) {
566 + if (data_len > 0) {
567 + LIBSSH2_FREE(session, data);
568 + }
569 + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
570 + "SFTP stat packet too short");
571 + }
572 +
573 /* this reads a u32 and stores it into a signed 32bit value */
574 link_len = _libssh2_ntohu32(data + 9);
575 if (link_len < target_len) {

  ViewVC Help
Powered by ViewVC 1.1.30