Bug 16303 - Missing Sanity Checks in R-3.1.x for various library function calls...
Summary: Missing Sanity Checks in R-3.1.x for various library function calls...
Status: NEW
Alias: None
Product: R
Classification: Unclassified
Component: Mac GUI / Mac specific (show other bugs)
Version: R 3.1.2
Hardware: All All
: P5 normal
Assignee: Simon Urbanek
URL:
Depends on:
Blocks:
 
Reported: 2015-04-06 17:04 UTC by Bill Parker
Modified: 2015-04-06 17:11 UTC (History)
1 user (show)

See Also:


Attachments
patch file for above bug report (486 bytes, patch)
2015-04-06 17:04 UTC, Bill Parker
Details | Diff
patch file for this bug report (2.44 KB, patch)
2015-04-06 17:05 UTC, Bill Parker
Details | Diff
Patch file for above bug report... (453 bytes, patch)
2015-04-06 17:06 UTC, Bill Parker
Details | Diff
patch file for above bug report (552 bytes, patch)
2015-04-06 17:06 UTC, Bill Parker
Details | Diff
patch file for above bug report (2.05 KB, patch)
2015-04-06 17:07 UTC, Bill Parker
Details | Diff
patch file for above bug report (533 bytes, patch)
2015-04-06 17:08 UTC, Bill Parker
Details | Diff
patch file for above bug report (409 bytes, patch)
2015-04-06 17:08 UTC, Bill Parker
Details | Diff
patch file for above bug report (1.67 KB, patch)
2015-04-06 17:09 UTC, Bill Parker
Details | Diff
patch file for above bug report (605 bytes, patch)
2015-04-06 17:10 UTC, Bill Parker
Details | Diff
patch file for above bug report (472 bytes, patch)
2015-04-06 17:11 UTC, Bill Parker
Details | Diff
patch file for above bug report (348 bytes, patch)
2015-04-06 17:11 UTC, Bill Parker
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Bill Parker 2015-04-06 17:04:32 UTC
Created attachment 1772 [details]
patch file for above bug report

Hello All,

    In reviewing source code in R-3.1.3, I found in directory
'R-3.1.3/src/extra/graphapp', file 'dialogs.c' a call to malloc()
which is not checked for a return value of NULL, indicating
failure.  The patch file which checks for this is below:

--- dialogs.c.orig      2015-04-04 16:48:58.688338975 -0700
+++ dialogs.c   2015-04-04 16:51:30.776668620 -0700
@@ -872,6 +872,8 @@
        end = sel.cpMax;
        if (start < end) {
            buf = (char *) malloc(end - start + 1);
+           if (buf == NULL) /* oops, out of memory, now what? */
+             return 0;   /* should we return zero here, or something else? */
            sendmessage(hwnd, EM_GETSELTEXT, 0, buf);
            if (!strcmp(buf, what)) {
                checklimittext(t, strlen(replacewith) - strlen(what) + 2);

In directory 'R-3.1.3/src/gnuwin32', file 'editor.c', I found several
instances of calls to malloc/calloc/realloc which are not checked for
a return value of NULL, indicating failure.  The patch file below 
corrects this issue:

--- editor.c.orig       2015-04-04 17:13:31.340505493 -0700
+++ editor.c    2015-04-04 17:25:37.590808172 -0700
@@ -60,12 +60,23 @@
 {
     EditorData p;
     p = (EditorData) malloc(sizeof(struct structEditorData));
+    if (p == NULL) /* no memory, now what? */
+      return NULL;
     p->file = file;
     /* need space for terminator, and to copy it */
     p->filename = (char *) malloc((MAX_PATH+1)*sizeof(char));
+    if (p->filename == NULL) { /* no memory, now what? */
+      free(p);
+      return NULL;
+    }
     if (filename)
        strncpy(p->filename, filename, MAX_PATH+1);
     p->title = (char *) malloc((EDITORMAXTITLE + 1)*sizeof(char));
+    if (p->title == NULL) { /* no memory, now what? */
+      free(p->filename);
+      free(p);
+      return NULL;
+    }
     p->title[EDITORMAXTITLE] = p->title[0] = '\0';
     return p;
 }
@@ -130,6 +141,11 @@
     bufsize = 0;
     while (num > 0) {
        buffer = realloc(buffer, bufsize + 3000 + 1);
+       if (buffer == NULL) { /* out of memory, now what? */
+           snprintf(tmp, MAX_PATH+50,
+               G_("unable to allocate memory for file '%s'"), sname);
+           return;
+       }
        num = fread(buffer + bufsize, 1, 3000 - 1, f);
        if (num >= 0) {
            bufsize += num;
@@ -267,6 +283,8 @@
            ++i; ++j;
        }
        linebuf = realloc(linebuf, (j+1)*sizeof(char));
+       if (linebuf == NULL) /* out of memory, now what? */
+         return NULL;
        strncpy(linebuf, &contents[istartline], j);
        linebuf[j] = '\0';
        gdrawstr(lpr, f, Black, pt(left, linep), linebuf);
@@ -471,6 +489,8 @@
 {
     int length = getlinelength(t); /* return character num */
     char *line = malloc(length * sizeof(WCHAR) + 2); /* Extra space for null and word length in getcurrentline */
+    if (line == NULL) /* no memory, now what? */
+       return NULL;
     memset(line, 0, length * sizeof(WCHAR) + 2);
     getcurrentline(t, line, length);
     consolecmd(RConsole, line);
@@ -774,6 +794,8 @@
 
     /* Packages menu should go here */
     p->pmenu = (PkgMenuItems) malloc(sizeof(struct structPkgMenuItems));
+    if (p->pmenu == NULL) /* out of memory, now what? */
+      return NULL;
     RguiPackageMenu(p->pmenu);
 
 #ifdef USE_MDI
@@ -784,6 +806,10 @@
     MCHECK(newmenuitem(G_("Editor"), 0, menueditorhelp));
     MCHECK(newmenuitem("-", 0, NULL));
     p->hmenu = (HelpMenuItems) malloc(sizeof(struct structHelpMenuItems));
+    if (p->hmenu == NULL) { /* out of memory, now what? */
+       free(p->pmenu);
+       return NULL;
+    } 
     RguiCommonHelp(m, p->hmenu);
 
     settextfont(t, editorfn);

In directory 'R-3.1.3/src/gnuwin32', file 'pager.c', I found a call
to malloc() w/out a check for a return value of NULL, indicating
failure.  The patch file below corrects this issue:

--- pager.c.orig        2015-04-04 17:35:40.622450393 -0700
+++ pager.c     2015-04-04 17:38:01.222319913 -0700
@@ -103,6 +103,11 @@
     p[rr] = '\0';
     cnt = mbstowcs(NULL, p, 0);
     wp = (wchar_t *) malloc((cnt+1) * sizeof(wchar_t));
+    if (!wp) {
+       free(p);
+       R_ShowMessage(G_("Insufficient memory to display file in internal pager"));
+       return NULL;
+    }
     mbstowcs(wp, p, cnt+1);
     for (q = wp, ms = 1, dim = cnt; *q; q++) {
        if (*q == '\t')

In directory 'R-3.1.3/src/gnuwin32', file 'preferences.c', I found
a call to malloc() which is not checked for a return value of NULL
indicating failure.  The patch file below corrects this issue:

--- preferences.c.orig  2015-04-04 17:42:02.345965488 -0700
+++ preferences.c       2015-04-04 17:44:43.078393754 -0700
@@ -303,6 +303,8 @@
 
     if(strcmp(newGUI->language, curGUI.language)) {
        char *buf = malloc(50);
+       if (!buf) /* out of memory, now what? */
+         return; /* do we need to warn the user that we are out of memory with msg? */ 
        askok(G_("The language for menus cannot be changed on a\n running console.\n\nSave the preferences and restart Rgui to apply to menus.\n"));
        snprintf(buf, 50, "LANGUAGE=%s", newGUI->language);
        putenv(buf);

In directory 'R-3.1.3/src/gnuwin32', file 'rui.c', there are numerous
instances of calls to malloc() w/out checks for NULL, indicating failure.

In directory 'R-3.1.3/src/library/grDevices/src', file 'devQuartz.c',
there are numerous instances of calls to malloc()/calloc() with FIXME
notations requesting checks for allocations.  The patch file below
adds the checks in question:

--- devQuartz.c.orig    2015-04-04 18:14:28.089259456 -0700
+++ devQuartz.c 2015-04-04 18:25:13.588299064 -0700
@@ -431,6 +431,8 @@
     dev->haveLocator = (def->locatePoint) ? 2 : 1;
 
     QuartzDesc *qd = calloc(1, sizeof(QuartzDesc));
+    if (!qd) 
+       error(_("unable to allocate memory for qd in QuartzDevice_Create,,,"));
     qd->width      = def->width;
     qd->height     = def->height;
     qd->userInfo   = def->userInfo;
@@ -917,6 +919,8 @@
         CFIndex length = CFStringGetLength(str);
        /* FIXME: check allocation */
         *buffer = malloc(length * sizeof(UniChar));
+       if (!buffer)
+           error(_("unable to allocate memory for buffer in text2unichar..."));
         CFStringGetCharacters(str, CFRangeMake(0, length), *buffer);
         *free = 1;
     }
@@ -941,7 +945,13 @@
     len = (int) CFStringGetLength(str);
     /* FIXME: check allocations */
     glyphs = malloc(sizeof(CGGlyph) * len);
+    if (!glyphs)
+       error(_("unable to allocate memory for glyphs in RQuartz_StrWidth..."));
     advances = malloc(sizeof(int) * len);
+    if (!advances) {
+       free(glyphs);
+       error(_("unable to allocate memory for advances in RQuartz_StrWidth..."));
+    }
     CGFontGetGlyphsForUnichars(font, buffer, glyphs, len);
     CGFontGetGlyphAdvances(font, glyphs, len, advances);
     float width = 0.0; /* aScale*CGFontGetLeading(CGContextGetFont(ctx)); */
@@ -976,9 +986,19 @@
     len = (int) CFStringGetLength(str);
     /* FIXME: check allocations */
     glyphs = malloc(sizeof(CGGlyph) * len);
+    if (!glyphs)
+       error(_("unable to allocate memory for glyphs in RQuartz_Text..."));
     CGFontGetGlyphsForUnichars(font, buffer, glyphs, len);
     int      *advances = malloc(sizeof(int) * len);
+    if (!advances) {
+       free(glyphs);
+       error(_("unable to allocate memory for advances in RQuartz_Text..."));
+    }
     CGSize   *g_adv    = malloc(sizeof(CGSize) * len);
+    if (!g_adv) {
+       free(advances);
+       free(glyphs);
+       error(_("unable to allocate memory for g_adv in RQuartz_Text..."));
 
     CGFontGetGlyphAdvances(font, glyphs, len, advances);
     for(i =0 ; i < len; i++) {

In directory '/R-3.1.3/src/library/grDevices/src', file 'qdBitmap.c',
the call to malloc() is not checked for a return value of NULL,
indicating failure (see FIXME), the patch file below corrects this
issue:

--- qdBitmap.c.orig     2015-04-04 18:31:47.844406988 -0700
+++ qdBitmap.c  2015-04-04 18:33:48.873789200 -0700
@@ -148,6 +148,10 @@
         /* Allocate sufficient space */
        /* FIXME: check allocations */
         QuartzBitmapDevice *dev = malloc(sizeof(QuartzBitmapDevice)+s);
+       if (!dev) {
+           warning(_("Unable to alloc memory for bitmap in Device Create "));
+           return ret;
+       }
         dev->length = (unsigned int) s;
         dev->uti  = type ? strdup(type) : NULL;
         dev->path = par->file ? strdup(par->file) : NULL;

In directory 'src/library/grDevices/src', file 'qdPDF.c', I found
a call to calloc() without a check for a return value of NULL,
indicating failure.  The patch file below corrects this issue:

--- qdPDF.c.orig        2015-04-05 08:32:01.343158800 -0700
+++ qdPDF.c     2015-04-05 08:33:40.446754357 -0700
@@ -88,6 +88,10 @@
     if (!qf) qf = fn;
 
     QuartzPDFDevice *dev = calloc(1, sizeof(QuartzPDFDevice));
+    if (dev == NULL) { /* oops, out of memory... */
+       warning(_("Out of memory in QuartzPDF_DeviceCreate"));
+       return ret;
+    }
 
     if ((!par->file || ! *par->file)) par->file = "Rplots.pdf";

In directory 'src/main', file 'Rdynload.c', I found calls to
calloc() without a check for a return value of NULL, indicating
failure, the patch file below corrects this issue:

--- Rdynload.c.orig     2015-04-05 16:33:59.459434662 -0700
+++ Rdynload.c  2015-04-05 16:44:08.874888232 -0700
@@ -259,6 +259,8 @@
        for(num = 0; croutines[num].name != NULL; num++) {;}
        info->CSymbols = (Rf_DotCSymbol*)calloc((size_t) num,
                                                sizeof(Rf_DotCSymbol));
+       if (!info->CSymbols)
+           error("allocation failure in R_registerRoutines (C)");
        info->numCSymbols = num;
        for(i = 0; i < num; i++) {
            R_addCRoutine(info, croutines+i, info->CSymbols + i);
@@ -270,6 +272,10 @@
        info->FortranSymbols =
            (Rf_DotFortranSymbol*)calloc((size_t) num,
                                         sizeof(Rf_DotFortranSymbol));
+       if (!info->FortranSymbols) {
+           free(info->CSymbols);
+           error("allocation failure in R_registerRoutines (Fortran)");
+       }
        info->numFortranSymbols = num;
        for(i = 0; i < num; i++)
            R_addFortranRoutine(info, fortranRoutines+i,
@@ -280,6 +286,11 @@
        for(num = 0; callRoutines[num].name != NULL; num++) {;}
        info->CallSymbols =
            (Rf_DotCallSymbol*)calloc((size_t) num, sizeof(Rf_DotCallSymbol));
+       if (!info->CallSymbols) {
+           free(info->FortranSymbols);
+           free(info->CSymbols);
+           error("allocation failure in R_registerRoutines (callRoutines)");
+       }
        info->numCallSymbols = num;
        for(i = 0; i < num; i++)
            R_addCallRoutine(info, callRoutines+i, info->CallSymbols + i);
@@ -290,6 +301,12 @@
        info->ExternalSymbols =
            (Rf_DotExternalSymbol*)calloc((size_t) num,
                                          sizeof(Rf_DotExternalSymbol));
+       if (!info->ExternalSymbols) {
+           free(info->CallSymbols);
+           free(info->FortranSymbols);
+           free(info->CSymbols);
+           error("allocation failure in R_registerRoutines (externalRoutines)");
+       }
        info->numExternalSymbols = num;
 
        for(i = 0; i < num; i++) 

In directory 'src/main', file 'agrep.c', I found 2 calls to malloc() w/out
a check for a return value of NULL, indicating failure.  The patch file
below corrects this issue:

--- agrep.c.orig        2015-04-05 16:50:25.226720615 -0700
+++ agrep.c     2015-04-05 16:53:54.070263555 -0700
@@ -625,6 +625,8 @@
            if(opt_counts) {
                nmatch = reg.re_nsub + 1;
                pmatch = (regmatch_t *) malloc(nmatch * sizeof(regmatch_t));
+               if (!pmatch)
+                   error(_("Unable to allocate memory..."));
            }
 
            for(j = 0; j < ny; j++) {
@@ -836,6 +838,8 @@
     nmatch = reg.re_nsub + 1;
 
     pmatch = (regmatch_t *) malloc(nmatch * sizeof(regmatch_t));
+    if (!pmatch)
+       error(_("Unable to allocate memory..."));
 
     tre_regaparams_default(&params);
     amatch_regaparams(&params, patlen,

In directory 'src/main', file 'connections.c', there is an instance
of a call to malloc() which fails to check for a return value of NULL
indicating failure.  The patch file below corrects this issue:

--- connections.c.orig  2015-04-05 17:05:52.196533711 -0700
+++ connections.c       2015-04-05 17:06:14.501368541 -0700
@@ -1021,6 +1021,7 @@
     */
     this->hdl_namedpipe = NULL;
     this->overlapped_write = (LPOVERLAPPED)malloc(sizeof(OVERLAPPED));
+    if (!this->overlapped_write) error(_("allocation of fifo write failed"));
     this->overlapped_write = CreateEventA(NULL, TRUE, TRUE, NULL);
     if (con->canwrite) {
        SECURITY_ATTRIBUTES win_namedpipe_secattr = {0};

In directory 'src/main', file 'gram.c', I found an instance where
a call to malloc() was not checked for a return value of NULL, indicating
failure.  The patch file below corrects this issue:

--- gram.c.orig 2015-04-05 17:16:32.058856922 -0700
+++ gram.c      2015-04-05 17:17:02.021665041 -0700
@@ -3515,6 +3515,7 @@
 {
     if (busy) {
        SrcRefState *prev = malloc(sizeof(SrcRefState));
+       if (!prev) error(_("unable to allocate buffer in SrcRefState"));
        PutSrcRefState(prev);
        ParseState.prevState = prev;
        ParseState.data = NULL;

		
I am attaching the patch file(s) to this bug report.

Bill Parker (wp02855 at gmail dot com)
Comment 1 Bill Parker 2015-04-06 17:05:31 UTC
Created attachment 1773 [details]
patch file for this bug report

patch file for 'editor.c' file...
Comment 2 Bill Parker 2015-04-06 17:06:14 UTC
Created attachment 1774 [details]
Patch file for above bug report...

patch file 'pager.c' for this bug report...
Comment 3 Bill Parker 2015-04-06 17:06:52 UTC
Created attachment 1775 [details]
patch file for above bug report

patch file 'preferences.c' for this bug report...
Comment 4 Bill Parker 2015-04-06 17:07:35 UTC
Created attachment 1776 [details]
patch file for above bug report

patch file 'devQuartz.c' for this bug report...
Comment 5 Bill Parker 2015-04-06 17:08:19 UTC
Created attachment 1777 [details]
patch file for above bug report

Patch file 'qdbitmap.c' for this bug report...
Comment 6 Bill Parker 2015-04-06 17:08:53 UTC
Created attachment 1778 [details]
patch file for above bug report

Patch file 'qdPDF.c' for this bug report...
Comment 7 Bill Parker 2015-04-06 17:09:37 UTC
Created attachment 1779 [details]
patch file for above bug report

Patch file 'RDynload.c' for this bug report...
Comment 8 Bill Parker 2015-04-06 17:10:32 UTC
Created attachment 1780 [details]
patch file for above bug report

Patch file 'agrep.c' for this bug report...
Comment 9 Bill Parker 2015-04-06 17:11:20 UTC
Created attachment 1781 [details]
patch file for above bug report

patch file 'connections.c' for this bug report...
Comment 10 Bill Parker 2015-04-06 17:11:56 UTC
Created attachment 1782 [details]
patch file for above bug report

patch file 'gram.c' for this bug report...