Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix fann_error buffer overflow #2

Merged
merged 4 commits into from
Aug 16, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 53 additions & 38 deletions src/fann_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <limits.h>

#include "config.h"
#include "fann.h"
Expand All @@ -30,6 +31,19 @@
#define snprintf _snprintf
#endif

/* define path max if not defined */
#if defined(_WIN32) && !defined(__MINGW32__)
#define PATH_MAX _MAX_PATH
#endif
#ifndef PATH_MAX
#ifdef _POSIX_PATH_MAX
#define PATH_MAX _POSIX_PATH_MAX
#else
#define PATH_MAX 4096
#endif
#endif


FILE * fann_default_error_log = (FILE *)-1;

/* resets the last error number
Expand Down Expand Up @@ -93,102 +107,103 @@ FANN_EXTERNAL void FANN_API fann_print_error(struct fann_error *errdat)
void fann_error(struct fann_error *errdat, const enum fann_errno_enum errno_f, ...)
{
va_list ap;
char *errstr;
size_t errstr_max = FANN_ERRSTR_MAX + PATH_MAX - 1;
char errstr[FANN_ERRSTR_MAX + PATH_MAX];
FILE * error_log = fann_default_error_log;

if(errdat != NULL)
errdat->errno_f = errno_f;

if(errdat != NULL && errdat->errstr != NULL)
{
errstr = errdat->errstr;
}
else
{
errstr = (char *) malloc(FANN_ERRSTR_MAX);
if(errstr == NULL)
{
fprintf(stderr, "Unable to allocate memory.\n");
return;
}
}

va_start(ap, errno_f);
switch (errno_f)
{
case FANN_E_NO_ERROR:
break;
return;
case FANN_E_CANT_OPEN_CONFIG_R:
vsprintf(errstr, "Unable to open configuration file \"%s\" for reading.\n", ap);
vsnprintf(errstr, errstr_max, "Unable to open configuration file \"%s\" for reading.\n", ap);
break;
case FANN_E_CANT_OPEN_CONFIG_W:
vsprintf(errstr, "Unable to open configuration file \"%s\" for writing.\n", ap);
vsnprintf(errstr, errstr_max, "Unable to open configuration file \"%s\" for writing.\n", ap);
break;
case FANN_E_WRONG_CONFIG_VERSION:
vsprintf(errstr,
vsnprintf(errstr, errstr_max,
"Wrong version of configuration file, aborting read of configuration file \"%s\".\n",
ap);
break;
case FANN_E_CANT_READ_CONFIG:
vsprintf(errstr, "Error reading \"%s\" from configuration file \"%s\".\n", ap);
vsnprintf(errstr, errstr_max, "Error reading \"%s\" from configuration file \"%s\".\n", ap);
break;
case FANN_E_CANT_READ_NEURON:
vsprintf(errstr, "Error reading neuron info from configuration file \"%s\".\n", ap);
vsnprintf(errstr, errstr_max, "Error reading neuron info from configuration file \"%s\".\n", ap);
break;
case FANN_E_CANT_READ_CONNECTIONS:
vsprintf(errstr, "Error reading connections from configuration file \"%s\".\n", ap);
vsnprintf(errstr, errstr_max, "Error reading connections from configuration file \"%s\".\n", ap);
break;
case FANN_E_WRONG_NUM_CONNECTIONS:
vsprintf(errstr, "ERROR connections_so_far=%d, total_connections=%d\n", ap);
vsnprintf(errstr, errstr_max, "ERROR connections_so_far=%d, total_connections=%d\n", ap);
break;
case FANN_E_CANT_OPEN_TD_W:
vsprintf(errstr, "Unable to open train data file \"%s\" for writing.\n", ap);
vsnprintf(errstr, errstr_max, "Unable to open train data file \"%s\" for writing.\n", ap);
break;
case FANN_E_CANT_OPEN_TD_R:
vsprintf(errstr, "Unable to open train data file \"%s\" for writing.\n", ap);
vsnprintf(errstr, errstr_max, "Unable to open train data file \"%s\" for writing.\n", ap);
break;
case FANN_E_CANT_READ_TD:
vsprintf(errstr, "Error reading info from train data file \"%s\", line: %d.\n", ap);
vsnprintf(errstr, errstr_max, "Error reading info from train data file \"%s\", line: %d.\n", ap);
break;
case FANN_E_CANT_ALLOCATE_MEM:
sprintf(errstr, "Unable to allocate memory.\n");
strcpy(errstr, "Unable to allocate memory.\n");
break;
case FANN_E_CANT_TRAIN_ACTIVATION:
sprintf(errstr, "Unable to train with the selected activation function.\n");
strcpy(errstr, "Unable to train with the selected activation function.\n");
break;
case FANN_E_CANT_USE_ACTIVATION:
sprintf(errstr, "Unable to use the selected activation function.\n");
strcpy(errstr, "Unable to use the selected activation function.\n");
break;
case FANN_E_TRAIN_DATA_MISMATCH:
sprintf(errstr, "Training data must be of equivalent structure.\n");
strcpy(errstr, "Training data must be of equivalent structure.\n");
break;
case FANN_E_CANT_USE_TRAIN_ALG:
sprintf(errstr, "Unable to use the selected training algorithm.\n");
strcpy(errstr, "Unable to use the selected training algorithm.\n");
break;
case FANN_E_TRAIN_DATA_SUBSET:
vsprintf(errstr, "Subset from %d of length %d not valid in training set of length %d.\n", ap);
vsnprintf(errstr, errstr_max, "Subset from %d of length %d not valid in training set of length %d.\n", ap);
break;
case FANN_E_INDEX_OUT_OF_BOUND:
vsprintf(errstr, "Index %d is out of bound.\n", ap);
vsnprintf(errstr, errstr_max, "Index %d is out of bound.\n", ap);
break;
case FANN_E_SCALE_NOT_PRESENT:
sprintf(errstr, "Scaling parameters not present.\n");
strcpy(errstr, "Scaling parameters not present.\n");
break;
case FANN_E_INPUT_NO_MATCH:
vsprintf(errstr, "The number of input neurons in the ann (%d) and data (%d) don't match\n", ap);
vsnprintf(errstr, errstr_max, "The number of input neurons in the ann (%d) and data (%d) don't match\n", ap);
break;
case FANN_E_OUTPUT_NO_MATCH:
vsprintf(errstr, "The number of output neurons in the ann (%d) and data (%d) don't match\n", ap);
vsnprintf(errstr, errstr_max, "The number of output neurons in the ann (%d) and data (%d) don't match\n", ap);
break;
case FANN_E_WRONG_PARAMETERS_FOR_CREATE:
sprintf(errstr, "The parameters for create_standard are wrong, either too few parameters provided or a negative/very high value provided.\n");
strcpy(errstr, "The parameters for create_standard are wrong, either too few parameters provided or a negative/very high value provided.\n");
break;
}
va_end(ap);

if(errdat != NULL)
{
errdat->errstr = errstr;
if(errdat->errstr == NULL)
{
errdat->errstr = malloc(strlen(errstr) + 1);
}
else if(strlen(errdat->errstr) < strlen(errstr))
{
errdat->errstr = realloc(errdat->errstr, strlen(errstr) + 1);
}
/* allocation failed */
if(errdat->errstr == NULL)
{
fprintf(stderr, "Unable to allocate memory.\n");
return;
}
strcpy(errdat->errstr, errstr);
error_log = errdat->error_log;
}

Expand Down
2 changes: 1 addition & 1 deletion src/include/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
########### install files ###############

INSTALL_FILES( /include FILES fann.h doublefann.h fann_internal.h floatfann.h fann_data.h fixedfann.h compat_time.h fann_activation.h fann_cascade.h fann_error.h fann_train.h fann_io.h fann_cpp.h )
INSTALL_FILES( /include FILES fann.h doublefann.h fann_internal.h floatfann.h fann_data.h fixedfann.h fann_activation.h fann_cascade.h fann_error.h fann_train.h fann_io.h fann_cpp.h )