I came across this bug while i found our SSL server was coring a few times a
day. I used dmalloc (www.dmalloc.com) to help trace it down to a client
using MSIE with SSLv3 off and using SSLv2. I have not tried but i assume
any SSLv2 client will cause the same results. It comes down to calculating
a wrong buffer size and overwriting a buffer limit. Here are the details:
ssl/s2_pkt.c line 453
453 static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int l
en)
454 {
455 unsigned int j,k,olen,p,mac_size,bs;
456 register unsigned char *pp;
457
458 olen=len;
459
460 /* first check if there is data from an encryption waiting to
461 * be sent - it must be sent because the other end is waiting.
462 * This will happen with non-blocking IO. We print it and then
463 * return.
464 */
465 if (s->s2->wpend_len != 0) return(write_pending(s,buf,len));
466
467 /* set mac_size to mac size */
468 if (s->s2->clear_text)
469 mac_size=0;
470 else
471 mac_size=EVP_MD_size(s->write_hash);
472
473 /* lets set the pad p */
474 if (s->s2->clear_text)
475 {
476 if (len > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER)
477 len=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER;
478 p=0;
479 s->s2->three_byte_header=0;
480 /* len=len; */
481 }
482 else
483 {
484 bs=EVP_CIPHER_CTX_block_size(s->enc_read_ctx);
485 j=len+mac_size;
486 if ((j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) &&
487 (!s->s2->escape))
488 {
489 if (j > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER)
490 j=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER;
491 /* set k to the max number of bytes with 2
492 * byte header */
493 k=j-(j%bs);
494 /* how many data bytes? */
495 len=k-mac_size;
496 s->s2->three_byte_header=0;
497 p=0;
498 }
499 else if ((bs <= 1) && (!s->s2->escape))
500 {
501 /* len=len; */
502 s->s2->three_byte_header=0;
503 p=0;
504 }
505 else /* 3 byte header */
506 {
507 /*len=len; */
508 p=(j%bs);
509 p=(p == 0)?0:(bs-p);
510 if (s->s2->escape)
511 s->s2->three_byte_header=1;
512 else
513 s->s2->three_byte_header=(p == 0)?0:1;
514 }
515 }
516 /* mac_size is the number of MAC bytes
517 * len is the number of data bytes we are going to send
518 * p is the number of padding bytes
519 * if p == 0, it is a 2 byte header */
520
521 s->s2->wlength=len;
522 s->s2->padding=p;
523 s->s2->mac_data= &(s->s2->wbuf[3]);
524 s->s2->wact_data= &(s->s2->wbuf[3+mac_size]);
525 /* we copy the data into s->s2->wbuf */
526 memcpy(s->s2->wact_data,buf,len);
...
SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER = 32767
SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER = 16383
s->s2->wbuf allocated with SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2 bytes
(s2_lib.c)
453: called with len = 32768
465: s->s2->wpend_len = 0, does not meet condition
468: s->s2->clear_text = 0
471: mac_size gets set to 16 (s->write_hash->md_size)
474: s->s2->clear_text = 0
484: bs set to 1 (s->enc_read_ctx->cipher->block_size)
485: j set to 32784 (32768 + 16)
486: j (32784) is > 16383 AND s->s2->escape = 0
489: j (32784) is > 32767
490: j set to 32767
493: k set to 32767 - (32767 % 1) = 32767
495: len = 32767 - 16 = 32751
...
524: s->s2->wact_data set to s->s2->wbuf[19], this leaves 32769 - 19 as a
buffer for s->s2->wact_data
526: 32751 bytes are written into s->s2->wact_data, which is 32750 bytes long
someone double check the math here, but i believe this is correct. if not
i'm sorry for whoevers time i wasted =)
i don't know the lib well enough to propose a fix, but i assume its just
adding a byte to the buffer or removing one from the length to copy
somewhere.
-Eric Day
[EMAIL PROTECTED]
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [EMAIL PROTECTED]
Automated List Manager [EMAIL PROTECTED]