Project

General

Profile

Enhancement #750 » 0014-sanitize-null-writes-write-errors-oversized-integers.patch

Loïc Gomez, 2022-01-10 19:28

View differences:

src/connection.c
211 211

  
212 212
	size = sizeof(char)*strlen(message);
213 213

  
214
	// let's not ERR (SSL_write doesn't allow 0 len writes)
215
	if (size == 0)
216
		return WRITE_OK;
217

  
218
	// this will fail anyways
219
	if (size > INT_MAX) {
220
		mylog(LOG_ERROR, "Message too long in SSL write_socket");
221
		return WRITE_ERROR;
222
	}
223

  
214 224
	if (!cn->client && cn->cert == NULL) {
215 225
		cn->cert = mySSL_get_cert(cn->ssl_h);
216 226
		if (cn->cert == NULL) {
......
218 228
			return WRITE_ERROR;
219 229
		}
220 230
	}
221
	count = SSL_write(cn->ssl_h, (const void *)message, size);
231
	count = SSL_write(cn->ssl_h, (const void *)message, (int)size);
222 232
	ERR_print_errors(errbio);
223 233
	if (count <= 0) {
224 234
		int err = SSL_get_error(cn->ssl_h, count);
......
233 243
		}
234 244
		return WRITE_ERROR;
235 245
	}
236
	if (count != size) {
246
	if (count != (int)size) {
237 247
		/* abnormal : openssl keeps writing until message is not fully
238 248
		 * sent */
239
		mylog(LOG_DEBUG, "only %d written while message length is %d",
249
		mylog(LOG_ERROR, "SSL_write wrote only %d while message length is %d",
240 250
				count,size);
241 251
	}
242 252

  
......
473 483
/* returns 1 if connection must be notified */
474 484
static int read_socket_SSL(connection_t *cn)
475 485
{
476
	int max, count;
486
	int count;
487
	size_t max;
488

  
489
	if (cn == NULL)
490
		return 0;
491

  
492
	if (cn->incoming_end >= CONN_BUFFER_SIZE) {
493
		mylog(LOG_ERROR, "read_socket_SSL: internal error");
494
		return -1;
495
	}
496

  
497
	max = sizeof(char)*(CONN_BUFFER_SIZE - cn->incoming_end);
498
	if (max > INT_MAX) {
499
		mylog(LOG_ERROR, "read_socket_SSL: cannot read that much data");
500
		return -1;
501
	}
477 502

  
478
	max = CONN_BUFFER_SIZE - cn->incoming_end;
479 503
	if (!cn->client && cn->cert == NULL) {
480 504
		cn->cert = mySSL_get_cert(cn->ssl_h);
481 505
		if (cn->cert == NULL) {
......
483 507
			return -1;
484 508
		}
485 509
	}
486
	count = SSL_read(cn->ssl_h, (void *)cn->incoming + cn->incoming_end,
487
			sizeof(char) * max);
510
	count = SSL_read(cn->ssl_h, (void *)(cn->incoming + cn->incoming_end),
511
			(int)max);
488 512
	ERR_print_errors(errbio);
489 513
	if (count < 0) {
490 514
		int err = SSL_get_error(cn->ssl_h, count);
......
510 534
			connection_close(cn);
511 535
		}
512 536
		return 1;
537
	} else {
538
		cn->incoming_end += (size_t)count;
539
		return 0;
513 540
	}
514

  
515
	cn->incoming_end += count;
516
	return 0;
517 541
}
518 542
#endif
519 543

  
520 544
/* returns 1 if connection must be notified */
521 545
static int read_socket(connection_t *cn)
522 546
{
523
	int max, count;
547
	ssize_t count;
548
	size_t max;
524 549

  
525 550
	if (cn == NULL)
526 551
		return 0;
527
	max = CONN_BUFFER_SIZE - cn->incoming_end;
528
	count = read(cn->handle, cn->incoming+cn->incoming_end,
529
			sizeof(char)*max);
552

  
553
	if (cn->incoming_end >= CONN_BUFFER_SIZE) {
554
		mylog(LOG_ERROR, "read_socket: internal error");
555
		return -1;
556
	}
557

  
558
	max = sizeof(char)*(CONN_BUFFER_SIZE - cn->incoming_end);
559
	count = read(cn->handle, cn->incoming+cn->incoming_end, max);
530 560
	if (count < 0) {
531 561
		if (errno == EAGAIN || errno == EINTR || errno == EINPROGRESS)
532 562
			return 0;
......
543 573
			connection_close(cn);
544 574
		}
545 575
		return 1;
576
	} else {
577
		cn->incoming_end += (unsigned)count;
578
		return 0;
546 579
	}
547

  
548
	cn->incoming_end += count;
549
	return 0;
550 580
}
551 581

  
552 582
static void data_find_lines(connection_t *cn)
src/connection.h
74 74
	time_t connect_time;
75 75
	time_t timeout;
76 76
	char *incoming;
77
	unsigned incoming_end;
77
	size_t incoming_end;
78 78
	list_t *outgoing;
79 79
	char *partial;
80 80
	list_t *incoming_lines;
src/irc.c
1293 1293
	}
1294 1294

  
1295 1295
	/* LINK(src) == LINK(dest) */
1296
	size_t len = strlen(irc_line_elem(line, 2)) + 5;
1296
	size_t len = strlen(irc_line_elem(line, 2)) + 6;
1297
	// snprintf fix                               ^
1298
	// ‘__builtin___snprintf_chk’ output may be truncated before the last format character
1297 1299
	char *tmp;
1298 1300

  
1299 1301
	if (len == 0)
......
2896 2898
static int bip_get_index(const char* str, char car)
2897 2899
{
2898 2900
	char *cur;
2899
	if ((cur = strchr(str, car)))
2900
		return cur - str + 1;
2901
	else
2901
	long diff;
2902
	if (!(cur = strchr(str, car)))
2902 2903
		return 0;
2904
	diff = cur - str + 1;
2905
	if (diff > INT_MAX)
2906
		fatal("bip_get_index: string too long");
2907
	return (int)diff;
2903 2908
}
2904 2909

  
2905 2910
static int bip_fls(long v)
src/log.c
1115 1115
static char *_log_wrap(const char *dest, const char *line)
1116 1116
{
1117 1117
	char *buf;
1118
	size_t count;
1118
	int count;
1119 1119

  
1120 1120
	buf = bip_malloc((size_t)LOGLINE_MAXLEN + 1);
1121 1121
	count = snprintf(buf, (size_t)LOGLINE_MAXLEN + 1,
1122 1122
			":" P_IRCMASK " PRIVMSG %s :%s\r\n", dest, line);
1123
	if (count < 0) {
1124
		mylog(LOG_ERROR, "_log_wrap: error on snprintf: %s",
1125
				strerror(errno));
1126
		buf[LOGLINE_MAXLEN - 2] = '\r';
1127
		buf[LOGLINE_MAXLEN - 1] = '\n';
1128
		buf[LOGLINE_MAXLEN] = 0;
1129
		return buf;
1130
	}
1123 1131
	if (count >= LOGLINE_MAXLEN + 1) {
1124
		mylog(LOG_DEBUG, "line too long");
1132
		mylog(LOG_WARN, "_log_wrap: line too long");
1125 1133
		buf[LOGLINE_MAXLEN - 2] = '\r';
1126 1134
		buf[LOGLINE_MAXLEN - 1] = '\n';
1127 1135
		buf[LOGLINE_MAXLEN] = 0;
......
1171 1179
void log_write(log_t *logdata, const char *destination, const char *str)
1172 1180
{
1173 1181
	logstore_t *store = log_find_file(logdata, destination);
1182
	size_t written;
1174 1183

  
1175 1184
	if (!store) {
1176 1185
		mylog(LOG_ERROR, "Unable to find/create logfile for '%s'",
1177 1186
				destination);
1178 1187
		return;
1179 1188
	}
1180
	_log_write(logdata, store, destination, str);
1189
	written = _log_write(logdata, store, destination, str);
1190
	if (written <= 0)
1191
		mylog(LOG_WARN, "log_write to '%s' failed", destination);
1181 1192
}
1182 1193

  
1183 1194
static list_t *log_all_logs = NULL;
1184
- 
(13-13/24)