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
size = sizeof(char)*strlen(message);
// let's not ERR (SSL_write doesn't allow 0 len writes)
if (size == 0)
return WRITE_OK;
// this will fail anyways
if (size > INT_MAX) {
mylog(LOG_ERROR, "Message too long in SSL write_socket");
return WRITE_ERROR;
}
if (!cn->client && cn->cert == NULL) {
cn->cert = mySSL_get_cert(cn->ssl_h);
if (cn->cert == NULL) {
......
return WRITE_ERROR;
}
}
count = SSL_write(cn->ssl_h, (const void *)message, size);
count = SSL_write(cn->ssl_h, (const void *)message, (int)size);
ERR_print_errors(errbio);
if (count <= 0) {
int err = SSL_get_error(cn->ssl_h, count);
......
}
return WRITE_ERROR;
}
if (count != size) {
if (count != (int)size) {
/* abnormal : openssl keeps writing until message is not fully
* sent */
mylog(LOG_DEBUG, "only %d written while message length is %d",
mylog(LOG_ERROR, "SSL_write wrote only %d while message length is %d",
count,size);
}
......
/* returns 1 if connection must be notified */
static int read_socket_SSL(connection_t *cn)
{
int max, count;
int count;
size_t max;
if (cn == NULL)
return 0;
if (cn->incoming_end >= CONN_BUFFER_SIZE) {
mylog(LOG_ERROR, "read_socket_SSL: internal error");
return -1;
}
max = sizeof(char)*(CONN_BUFFER_SIZE - cn->incoming_end);
if (max > INT_MAX) {
mylog(LOG_ERROR, "read_socket_SSL: cannot read that much data");
return -1;
}
max = CONN_BUFFER_SIZE - cn->incoming_end;
if (!cn->client && cn->cert == NULL) {
cn->cert = mySSL_get_cert(cn->ssl_h);
if (cn->cert == NULL) {
......
return -1;
}
}
count = SSL_read(cn->ssl_h, (void *)cn->incoming + cn->incoming_end,
sizeof(char) * max);
count = SSL_read(cn->ssl_h, (void *)(cn->incoming + cn->incoming_end),
(int)max);
ERR_print_errors(errbio);
if (count < 0) {
int err = SSL_get_error(cn->ssl_h, count);
......
connection_close(cn);
}
return 1;
} else {
cn->incoming_end += (size_t)count;
return 0;
}
cn->incoming_end += count;
return 0;
}
#endif
/* returns 1 if connection must be notified */
static int read_socket(connection_t *cn)
{
int max, count;
ssize_t count;
size_t max;
if (cn == NULL)
return 0;
max = CONN_BUFFER_SIZE - cn->incoming_end;
count = read(cn->handle, cn->incoming+cn->incoming_end,
sizeof(char)*max);
if (cn->incoming_end >= CONN_BUFFER_SIZE) {
mylog(LOG_ERROR, "read_socket: internal error");
return -1;
}
max = sizeof(char)*(CONN_BUFFER_SIZE - cn->incoming_end);
count = read(cn->handle, cn->incoming+cn->incoming_end, max);
if (count < 0) {
if (errno == EAGAIN || errno == EINTR || errno == EINPROGRESS)
return 0;
......
connection_close(cn);
}
return 1;
} else {
cn->incoming_end += (unsigned)count;
return 0;
}
cn->incoming_end += count;
return 0;
}
static void data_find_lines(connection_t *cn)
src/connection.h
time_t connect_time;
time_t timeout;
char *incoming;
unsigned incoming_end;
size_t incoming_end;
list_t *outgoing;
char *partial;
list_t *incoming_lines;
src/irc.c
}
/* LINK(src) == LINK(dest) */
size_t len = strlen(irc_line_elem(line, 2)) + 5;
size_t len = strlen(irc_line_elem(line, 2)) + 6;
// snprintf fix ^
// ‘__builtin___snprintf_chk’ output may be truncated before the last format character
char *tmp;
if (len == 0)
......
static int bip_get_index(const char* str, char car)
{
char *cur;
if ((cur = strchr(str, car)))
return cur - str + 1;
else
long diff;
if (!(cur = strchr(str, car)))
return 0;
diff = cur - str + 1;
if (diff > INT_MAX)
fatal("bip_get_index: string too long");
return (int)diff;
}
static int bip_fls(long v)
src/log.c
static char *_log_wrap(const char *dest, const char *line)
{
char *buf;
size_t count;
int count;
buf = bip_malloc((size_t)LOGLINE_MAXLEN + 1);
count = snprintf(buf, (size_t)LOGLINE_MAXLEN + 1,
":" P_IRCMASK " PRIVMSG %s :%s\r\n", dest, line);
if (count < 0) {
mylog(LOG_ERROR, "_log_wrap: error on snprintf: %s",
strerror(errno));
buf[LOGLINE_MAXLEN - 2] = '\r';
buf[LOGLINE_MAXLEN - 1] = '\n';
buf[LOGLINE_MAXLEN] = 0;
return buf;
}
if (count >= LOGLINE_MAXLEN + 1) {
mylog(LOG_DEBUG, "line too long");
mylog(LOG_WARN, "_log_wrap: line too long");
buf[LOGLINE_MAXLEN - 2] = '\r';
buf[LOGLINE_MAXLEN - 1] = '\n';
buf[LOGLINE_MAXLEN] = 0;
......
void log_write(log_t *logdata, const char *destination, const char *str)
{
logstore_t *store = log_find_file(logdata, destination);
size_t written;
if (!store) {
mylog(LOG_ERROR, "Unable to find/create logfile for '%s'",
destination);
return;
}
_log_write(logdata, store, destination, str);
written = _log_write(logdata, store, destination, str);
if (written <= 0)
mylog(LOG_WARN, "log_write to '%s' failed", destination);
}
static list_t *log_all_logs = NULL;
(13-13/24)