comparison packet.c @ 1580:7f2be495dff6 coverity

merge coverity
author Matt Johnston <matt@ucc.asn.au>
date Sun, 04 Mar 2018 15:07:09 +0800
parents 399d8eb961b5
children 8f7b6f75aa58
comparison
equal deleted inserted replaced
1545:0b991dec7ab9 1580:7f2be495dff6
33 #include "dbrandom.h" 33 #include "dbrandom.h"
34 #include "service.h" 34 #include "service.h"
35 #include "auth.h" 35 #include "auth.h"
36 #include "channel.h" 36 #include "channel.h"
37 #include "netio.h" 37 #include "netio.h"
38 #include "runopts.h"
38 39
39 static int read_packet_init(void); 40 static int read_packet_init(void);
40 static void make_mac(unsigned int seqno, const struct key_context_directional * key_state, 41 static void make_mac(unsigned int seqno, const struct key_context_directional * key_state,
41 buffer * clear_buf, unsigned int clear_len, 42 buffer * clear_buf, unsigned int clear_len,
42 unsigned char *output_mac); 43 unsigned char *output_mac);
62 unsigned int iov_count = 50; 63 unsigned int iov_count = 50;
63 struct iovec iov[50]; 64 struct iovec iov[50];
64 #else 65 #else
65 int len; 66 int len;
66 buffer* writebuf; 67 buffer* writebuf;
67 int packet_type;
68 #endif 68 #endif
69 69
70 TRACE2(("enter write_packet")) 70 TRACE2(("enter write_packet"))
71 dropbear_assert(!isempty(&ses.writequeue)); 71 dropbear_assert(!isempty(&ses.writequeue));
72 72
74 74
75 packet_queue_to_iovec(&ses.writequeue, iov, &iov_count); 75 packet_queue_to_iovec(&ses.writequeue, iov, &iov_count);
76 /* This may return EAGAIN. The main loop sometimes 76 /* This may return EAGAIN. The main loop sometimes
77 calls write_packet() without bothering to test with select() since 77 calls write_packet() without bothering to test with select() since
78 it's likely to be necessary */ 78 it's likely to be necessary */
79 #if DROPBEAR_FUZZ
80 if (fuzz.fuzzing) {
81 /* pretend to write one packet at a time */
82 /* TODO(fuzz): randomise amount written based on the fuzz input */
83 written = iov[0].iov_len;
84 }
85 else
86 #endif
87 {
79 written = writev(ses.sock_out, iov, iov_count); 88 written = writev(ses.sock_out, iov, iov_count);
80 if (written < 0) { 89 if (written < 0) {
81 if (errno == EINTR || errno == EAGAIN) { 90 if (errno == EINTR || errno == EAGAIN) {
82 TRACE2(("leave write_packet: EINTR")) 91 TRACE2(("leave write_packet: EINTR"))
83 return; 92 return;
84 } else { 93 } else {
85 dropbear_exit("Error writing: %s", strerror(errno)); 94 dropbear_exit("Error writing: %s", strerror(errno));
86 } 95 }
87 } 96 }
97 }
88 98
89 packet_queue_consume(&ses.writequeue, written); 99 packet_queue_consume(&ses.writequeue, written);
90 ses.writequeue_len -= written; 100 ses.writequeue_len -= written;
91 101
92 if (written == 0) { 102 if (written == 0) {
93 ses.remoteclosed(); 103 ses.remoteclosed();
94 } 104 }
95 105
96 #else /* No writev () */ 106 #else /* No writev () */
107 #if DROPBEAR_FUZZ
108 _Static_assert(0, "No fuzzing code for no-writev writes");
109 #endif
97 /* Get the next buffer in the queue of encrypted packets to write*/ 110 /* Get the next buffer in the queue of encrypted packets to write*/
98 writebuf = (buffer*)examine(&ses.writequeue); 111 writebuf = (buffer*)examine(&ses.writequeue);
99 112
100 /* The last byte of the buffer is not to be transmitted, but is 113 /* The last byte of the buffer is not to be transmitted, but is
101 * a cleartext packet_type indicator */ 114 * a cleartext packet_type indicator */
102 packet_type = writebuf->data[writebuf->len-1]; 115 len = writebuf->len - writebuf->pos;
103 len = writebuf->len - 1 - writebuf->pos;
104 TRACE2(("write_packet type %d len %d/%d", packet_type,
105 len, writebuf->len-1))
106 dropbear_assert(len > 0); 116 dropbear_assert(len > 0);
107 /* Try to write as much as possible */ 117 /* Try to write as much as possible */
108 written = write(ses.sock_out, buf_getptr(writebuf, len), len); 118 written = write(ses.sock_out, buf_getptr(writebuf, len), len);
109 119
110 if (written < 0) { 120 if (written < 0) {
349 mac_size = ses.keys->recv.algo_mac->hashsize; 359 mac_size = ses.keys->recv.algo_mac->hashsize;
350 contents_len = ses.readbuf->len - mac_size; 360 contents_len = ses.readbuf->len - mac_size;
351 361
352 buf_setpos(ses.readbuf, 0); 362 buf_setpos(ses.readbuf, 0);
353 make_mac(ses.recvseq, &ses.keys->recv, ses.readbuf, contents_len, mac_bytes); 363 make_mac(ses.recvseq, &ses.keys->recv, ses.readbuf, contents_len, mac_bytes);
364
365 #if DROPBEAR_FUZZ
366 if (fuzz.fuzzing) {
367 /* fail 1 in 2000 times to test error path.
368 note that mac_bytes is all zero prior to kex, so don't test ==0 ! */
369 unsigned int value = *((unsigned int*)&mac_bytes);
370 if (value % 2000 == 99) {
371 return DROPBEAR_FAILURE;
372 }
373 return DROPBEAR_SUCCESS;
374 }
375 #endif
354 376
355 /* compare the hash */ 377 /* compare the hash */
356 buf_setpos(ses.readbuf, contents_len); 378 buf_setpos(ses.readbuf, contents_len);
357 if (constant_time_memcmp(mac_bytes, buf_getptr(ses.readbuf, mac_size), mac_size) != 0) { 379 if (constant_time_memcmp(mac_bytes, buf_getptr(ses.readbuf, mac_size), mac_size) != 0) {
358 return DROPBEAR_FAILURE; 380 return DROPBEAR_FAILURE;
576 buf_putbytes(writebuf, mac_bytes, mac_size); 598 buf_putbytes(writebuf, mac_bytes, mac_size);
577 599
578 /* Update counts */ 600 /* Update counts */
579 ses.kexstate.datatrans += writebuf->len; 601 ses.kexstate.datatrans += writebuf->len;
580 602
581 writebuf_enqueue(writebuf, packet_type); 603 writebuf_enqueue(writebuf);
582 604
583 /* Update counts */ 605 /* Update counts */
584 ses.transseq++; 606 ses.transseq++;
585 607
586 now = monotonic_now(); 608 now = monotonic_now();
596 } 618 }
597 619
598 TRACE2(("leave encrypt_packet()")) 620 TRACE2(("leave encrypt_packet()"))
599 } 621 }
600 622
601 void writebuf_enqueue(buffer * writebuf, unsigned char packet_type) { 623 void writebuf_enqueue(buffer * writebuf) {
602 /* The last byte of the buffer stores the cleartext packet_type. It is not
603 * transmitted but is used for transmit timeout purposes */
604 buf_putbyte(writebuf, packet_type);
605 /* enqueue the packet for sending. It will get freed after transmission. */ 624 /* enqueue the packet for sending. It will get freed after transmission. */
606 buf_setpos(writebuf, 0); 625 buf_setpos(writebuf, 0);
607 enqueue(&ses.writequeue, (void*)writebuf); 626 enqueue(&ses.writequeue, (void*)writebuf);
608 ses.writequeue_len += writebuf->len-1; 627 ses.writequeue_len += writebuf->len;
609 } 628 }
610 629
611 630
612 /* Create the packet mac, and append H(seqno|clearbuf) to the output */ 631 /* Create the packet mac, and append H(seqno|clearbuf) to the output */
613 /* output_mac must have ses.keys->trans.algo_mac->hashsize bytes. */ 632 /* output_mac must have ses.keys->trans.algo_mac->hashsize bytes. */