Changeset: 7e44a580b7f9 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=7e44a580b7f9
Modified Files:
        clients/mapiclient/ReadlineTools.c
        gdk/gdk_bbp.c
        gdk/gdk_logger.c
        monetdb5/mal/mal_linker.c
        monetdb5/mal/mal_profiler.c
        monetdb5/modules/mal/bbp.c
        monetdb5/modules/mal/tokenizer.c
        monetdb5/modules/mal/wlc.c
        sql/backends/monet5/wlr.c
Branch: Aug2018
Log Message:

Check for snprintf usage on file paths. The output buffer should never get 
truncated (i.e. snprintf return FILENAME_MAX or more).


diffs (truncated from 498 to 300 lines):

diff --git a/clients/mapiclient/ReadlineTools.c 
b/clients/mapiclient/ReadlineTools.c
--- a/clients/mapiclient/ReadlineTools.c
+++ b/clients/mapiclient/ReadlineTools.c
@@ -321,18 +321,25 @@ init_readline(Mapi mid, char *lang, int 
        }
 
        if (save_history) {
+               int len;
 #ifndef NATIVE_WIN32
                if (getenv("HOME") != NULL) {
-                       snprintf(_history_file, FILENAME_MAX,
+                       len = snprintf(_history_file, FILENAME_MAX,
                                 "%s/.mapiclient_history_%s",
                                 getenv("HOME"), language);
-                       _save_history = 1;
+                       if (len == -1 || len >= FILENAME_MAX)
+                               fprintf(stderr, "Warning: history filename path 
is too large\n");
+                       else
+                               _save_history = 1;
                }
 #else
-               snprintf(_history_file, FILENAME_MAX,
+               len = snprintf(_history_file, FILENAME_MAX,
                         "%s%c_mapiclient_history_%s",
                         mo_find_option(NULL, 0, "prefix"), DIR_SEP, language);
-               _save_history = 1;
+               if (len == -1 || len >= FILENAME_MAX)
+                       fprintf(stderr, "Warning: history filename path is too 
large\n");
+               else
+                       _save_history = 1;
 #endif
                if (_save_history) {
                        FILE *f;
diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -801,6 +801,7 @@ fixfloatbats(void)
        char filename[FILENAME_MAX];
        FILE *fp;
        size_t len;
+       int written;
 
        for (bid = 1; bid < (bat) ATOMIC_GET(BBPsize, BBPsizeLock); bid++) {
                if ((b = BBP_desc(bid)) == NULL) {
@@ -815,10 +816,13 @@ fixfloatbats(void)
                         * logger that it also needs to do a
                         * conversion.  That is done by creating a
                         * file here based on the name of this BAT. */
-                       snprintf(filename, sizeof(filename),
+                       written = snprintf(filename, sizeof(filename),
                                 "%s/%.*s_nil-nan-convert",
                                 BBPfarms[0].dirname,
                                 (int) (len - 12), BBP_logical(bid));
+                       if (written == -1 || written >= FILENAME_MAX)
+                               GDKfatal("fixfloatbats: cannot create file %s 
has a very large pathname\n",
+                                                filename);
                        fp = fopen(filename, "w");
                        if (fp == NULL)
                                GDKfatal("fixfloatbats: cannot create file 
%s\n",
diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c
--- a/gdk/gdk_logger.c
+++ b/gdk/gdk_logger.c
@@ -1161,6 +1161,7 @@ logger_readlogs(logger *lg, FILE *fp, ch
 {
        gdk_return res = GDK_SUCCEED;
        char id[BUFSIZ];
+       int len;
 
        if (lg->debug & 1) {
                fprintf(stderr, "#logger_readlogs logger id is " LLFMT "\n", 
lg->id);
@@ -1176,11 +1177,15 @@ logger_readlogs(logger *lg, FILE *fp, ch
 
                if (!lg->shared && lid >= lg->id) {
                        lg->id = lid;
-                       snprintf(log_filename, sizeof(log_filename), "%s." 
LLFMT, filename, lg->id);
+                       len = snprintf(log_filename, sizeof(log_filename), 
"%s." LLFMT, filename, lg->id);
+                       if (len == -1 || len >= FILENAME_MAX)
+                               GDKerror("Logger filename path is too large\n");
                        res = logger_readlog(lg, log_filename);
                } else {
                        while (lid >= lg->id && res == GDK_SUCCEED) {
-                               snprintf(log_filename, sizeof(log_filename), 
"%s." LLFMT, filename, lg->id);
+                               len = snprintf(log_filename, 
sizeof(log_filename), "%s." LLFMT, filename, lg->id);
+                               if (len == -1 || len >= FILENAME_MAX)
+                                       GDKerror("Logger filename path is too 
large\n");
                                if ((res = logger_readlog(lg, log_filename)) != 
GDK_SUCCEED && lg->shared && lg->id > 1) {
                                        /* The only special case is if
                                         * the file is missing
@@ -1428,7 +1433,7 @@ static int
 logger_set_logdir_path(char *filename, const char *fn,
                       const char *logdir, int shared)
 {
-       int role = PERSISTENT; /* default role is persistent, i.e. the default 
dbfarm */
+       int len, role = PERSISTENT; /* default role is persistent, i.e. the 
default dbfarm */
 
        if (MT_path_absolute(logdir)) {
                char logdir_parent_path[FILENAME_MAX] = "";
@@ -1440,8 +1445,10 @@ logger_set_logdir_path(char *filename, c
                        /* set the new relative logdir location
                         * including the logger function name
                         * subdir */
-                       snprintf(filename, FILENAME_MAX, "%s%c%s%c",
+                       len = snprintf(filename, FILENAME_MAX, "%s%c%s%c",
                                 logdir_name, DIR_SEP, fn, DIR_SEP);
+                       if (len == -1 || len >= FILENAME_MAX)
+                               GDKerror("Logger filename path is too large\n");
 
                        /* add a new dbfarm for the logger directory
                         * using the parent dir path, assuming it is
@@ -1458,8 +1465,10 @@ logger_set_logdir_path(char *filename, c
                }
        } else {
                /* just concat the logdir and fn with appropriate separators */
-               snprintf(filename, FILENAME_MAX, "%s%c%s%c",
+               len = snprintf(filename, FILENAME_MAX, "%s%c%s%c",
                         logdir, DIR_SEP, fn, DIR_SEP);
+               if (len == -1 || len >= FILENAME_MAX)
+                       GDKerror("Logger filename path is too large\n");
        }
 
        return role;
@@ -1472,7 +1481,7 @@ logger_set_logdir_path(char *filename, c
 static gdk_return
 logger_load(int debug, const char *fn, char filename[FILENAME_MAX], logger *lg)
 {
-       int id = LOG_SID;
+       int len, id = LOG_SID;
        FILE *fp = NULL;
        char bak[FILENAME_MAX];
        str filenamestr = NULL;
@@ -1483,8 +1492,12 @@ logger_load(int debug, const char *fn, c
        if(!(filenamestr = GDKfilepath(farmid, lg->dir, LOGFILE, NULL)))
                goto error;
        snprintf(filename, FILENAME_MAX, "%s", filenamestr);
-       snprintf(bak, sizeof(bak), "%s.bak", filename);
+       len = snprintf(bak, sizeof(bak), "%s.bak", filename);
        GDKfree(filenamestr);
+       if (len == -1 || len >= FILENAME_MAX) {
+               GDKerror("Logger filename path is too large\n");
+               goto error;
+       }
 
        lg->catalog_bid = NULL;
        lg->catalog_nme = NULL;
@@ -1883,11 +1896,19 @@ logger_load(int debug, const char *fn, c
                /* Do not do conversion if logger is shared/read-only */
                if (!lg->shared) {
                        FILE *fp1;
-                       int curid;
-
-                       snprintf(cvfile, sizeof(cvfile), "%sconvert-nil-nan",
+                       int len, curid;
+
+                       len = snprintf(cvfile, sizeof(cvfile), 
"%sconvert-nil-nan",
                                 lg->dir);
-                       snprintf(bak, sizeof(bak), "%s_nil-nan-convert", fn);
+                       if (len == -1 || len >= FILENAME_MAX) {
+                               GDKerror("Convert-nil-nan filename path is too 
large\n");
+                               goto error;
+                       }
+                       len = snprintf(bak, sizeof(bak), "%s_nil-nan-convert", 
fn);
+                       if (len == -1 || len >= FILENAME_MAX) {
+                               GDKerror("Convert-nil-nan filename path is too 
large\n");
+                               goto error;
+                       }
                        /* read the current log id without disturbing
                         * the file pointer */
 #ifdef _MSC_VER
@@ -2215,7 +2236,7 @@ logger_exit(logger *lg)
 {
        FILE *fp;
        char filename[FILENAME_MAX];
-       int farmid = BBPselectfarm(lg->dbfarm_role, 0, offheap);
+       int len, farmid = BBPselectfarm(lg->dbfarm_role, 0, offheap);
 
        logger_close(lg);
        if (GDKmove(farmid, lg->dir, LOGFILE, NULL, lg->dir, LOGFILE, "bak") != 
GDK_SUCCEED) {
@@ -2224,7 +2245,11 @@ logger_exit(logger *lg)
                return GDK_FAIL;
        }
 
-       snprintf(filename, sizeof(filename), "%s%s", lg->dir, LOGFILE);
+       len = snprintf(filename, sizeof(filename), "%s%s", lg->dir, LOGFILE);
+       if (len == -1 || len >= FILENAME_MAX) {
+               fprintf(stderr, "!ERROR: logger_exit: logger filename path is 
too large\n");
+               return GDK_FAIL;
+       }
        if ((fp = GDKfileopen(farmid, NULL, filename, NULL, "w")) != NULL) {
                char ext[FILENAME_MAX];
 
@@ -2427,9 +2452,13 @@ logger_read_last_transaction_id(logger *
        FILE *fp;
        char id[BUFSIZ];
        lng lid = GDK_FAIL;
-       int farmid = BBPselectfarm(role, 0, offheap);
-
-       snprintf(filename, sizeof(filename), "%s%s", dir, logger_file);
+       int len, farmid = BBPselectfarm(role, 0, offheap);
+
+       len = snprintf(filename, sizeof(filename), "%s%s", dir, logger_file);
+       if (len == -1 || len >= FILENAME_MAX) {
+               fprintf(stderr, "!ERROR: logger_read_last_transaction_id: 
logger filename path is too large\n");
+               return -1;
+       }
        if ((fp = GDKfileopen(farmid, NULL, filename, NULL, "r")) == NULL) {
                fprintf(stderr, "!ERROR: logger_read_last_transaction_id: 
unable to open file %s\n", filename);
                return -1;
diff --git a/monetdb5/mal/mal_linker.c b/monetdb5/mal/mal_linker.c
--- a/monetdb5/mal/mal_linker.c
+++ b/monetdb5/mal/mal_linker.c
@@ -179,6 +179,7 @@ loadLibrary(str filename, int flag)
        }
 
        while (*mod_path) {
+               int len;
                char *p;
 
                for (p = mod_path; *p && *p != PATH_SEP; p++)
@@ -186,38 +187,41 @@ loadLibrary(str filename, int flag)
 
                /* try hardcoded SO_EXT if that is the same for modules */
 #ifdef _AIX
-               snprintf(nme, FILENAME_MAX, "%.*s%c%s_%s%s(%s_%s.0)",
+               len = snprintf(nme, FILENAME_MAX, "%.*s%c%s_%s%s(%s_%s.0)",
                                 (int) (p - mod_path),
                                 mod_path, DIR_SEP, SO_PREFIX, s, SO_EXT, 
SO_PREFIX, s);
 #else
-               snprintf(nme, FILENAME_MAX, "%.*s%c%s_%s%s",
+               len = snprintf(nme, FILENAME_MAX, "%.*s%c%s_%s%s",
                                 (int) (p - mod_path),
                                 mod_path, DIR_SEP, SO_PREFIX, s, SO_EXT);
 #endif
+               if (len == -1 || len >= FILENAME_MAX)
+                       throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR 
"Library filename path is too large");
                handle = dlopen(nme, mode);
-               if (handle == NULL && fileexists(nme)) {
+               if (handle == NULL && fileexists(nme))
                        throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR " 
failed to open library %s (from within file '%s'): %s", s, nme, dlerror());
-               }
                if (handle == NULL && strcmp(SO_EXT, ".so") != 0) {
                        /* try .so */
-                       snprintf(nme, FILENAME_MAX, "%.*s%c%s_%s.so",
+                       len = snprintf(nme, FILENAME_MAX, "%.*s%c%s_%s.so",
                                         (int) (p - mod_path),
                                         mod_path, DIR_SEP, SO_PREFIX, s);
+                       if (len == -1 || len >= FILENAME_MAX)
+                               throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR 
"Library filename path is too large");
                        handle = dlopen(nme, mode);
-                       if (handle == NULL && fileexists(nme)) {
+                       if (handle == NULL && fileexists(nme))
                                throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR 
" failed to open library %s (from within file '%s'): %s", s, nme, dlerror());
-                       }
                }
 #ifdef __APPLE__
                if (handle == NULL && strcmp(SO_EXT, ".bundle") != 0) {
                        /* try .bundle */
-                       snprintf(nme, FILENAME_MAX, "%.*s%c%s_%s.bundle",
+                       len = snprintf(nme, FILENAME_MAX, "%.*s%c%s_%s.bundle",
                                         (int) (p - mod_path),
                                         mod_path, DIR_SEP, SO_PREFIX, s);
+                       if (len == -1 || len >= FILENAME_MAX)
+                               throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR 
"Library filename path is too large");
                        handle = dlopen(nme, mode);
-                       if (handle == NULL && fileexists(nme)) {
+                       if (handle == NULL && fileexists(nme))
                                throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR 
" failed to open library %s (from within file '%s'): %s", s, nme, dlerror());
-                       }
                }
 #endif
 
@@ -247,8 +251,8 @@ loadLibrary(str filename, int flag)
                }
                filesLoaded[lastfile].fullname = GDKstrdup(handle ? nme : "");
                if(filesLoaded[lastfile].fullname == NULL) {
+                       GDKfree(filesLoaded[lastfile].modname);
                        MT_lock_unset(&mal_contextLock);
-                       GDKfree(filesLoaded[lastfile].modname);
                        if (handle)
                                dlclose(handle);
                        throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR " could 
not allocate space");
diff --git a/monetdb5/mal/mal_profiler.c b/monetdb5/mal/mal_profiler.c
--- a/monetdb5/mal/mal_profiler.c
+++ b/monetdb5/mal/mal_profiler.c
@@ -585,20 +585,29 @@ static int tracecounter = 0;
 str
 startTrace(str path)
 {
+       int len;
        char buf[FILENAME_MAX];
 
-       if( path && eventstream == NULL){
+       if (path && eventstream == NULL){
                // create a file to keep the events, unless we
                // already have a profiler stream
                MT_lock_set(&mal_profileLock );
-               if(eventstream == NULL && offlinestore ==0){
-                       
snprintf(buf,FILENAME_MAX,"%s%c%s",GDKgetenv("gdk_dbpath"), DIR_SEP, path);
+               if (eventstream == NULL && offlinestore ==0){
+                       len = 
snprintf(buf,FILENAME_MAX,"%s%c%s",GDKgetenv("gdk_dbpath"), DIR_SEP, path);
+                       if (len == -1 || len >= FILENAME_MAX) {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to