Please stop replying to this thread, this is not an OpenBSD problem at all.

> 
> Reading the documentation on fparseln (and the underlying fgetln) as
> well as on strsep, I see two potentially fatal errors in that code. I
> stopped trying after noticing the second issue.
> 
> If you can spot one of them, and feel you are unable to spot the
> other, please email me (off list) with the one you found and I'll try
> to remember the other one for you.  (Do not take too long, though,
> because I'll probably forget about this after a few days.)
> 
> Note, of course, that solving two problems does not mean that there
> are only two problems.
> 
> Thanks,
> 
> -- 
> Raul
> 
> On Wed, Aug 24, 2016 at 1:39 PM, Pavan Maddamsetti
> <[email protected]> wrote:
> > Here's the data structure:
> >
> > struct node {
> >         unsigned char end;
> >         unsigned char letter;
> >         unsigned char nchild;
> >         struct node **child;
> > };
> >
> > struct tree {
> >         struct node *root;
> > };
> >
> > And the code:
> >
> > int
> > load(struct tree *tree, FILE *fp)
> > {
> >         char *line, *word;
> >         const char ws[] = " \t";
> >
> >         while ((line = fparseln(fp, NULL, NULL, NULL, 0))) {
> >                 while ((word = strsep(&line, ws)))
> >                         if (*word)
> >                                 load_word(tree, word);
> >                 free(line);
> >         }
> >
> >         return (ferror(fp)) ? 0 : 1;
> > }
> >
> > int
> > load_word(struct tree *tree, char *word)
> > {
> >         struct node *node, *child, **newp;
> >         unsigned char c, i, j;
> >         const char *errstr;
> >
> >         if (*word == '\0') {
> >                 errstr = "empty word";
> >                 goto fail;
> >         }
> >
> >         node = tree->root;
> >         while ((c = *word++) != '\0') {
> >                 if (c >= 'A' && c <= 'Z')
> >                         c = c - 'A' + 'a';
> >                 if (!(c >= 'a' && c <= 'z'))
> >                         continue;
> >
> >                 for (i = 0; i < node->nchild; i++)
> >                         if (c <= node->child[i]->letter)
> >                                 break;
> >
> >                 if (i < node->nchild && c == node->child[i]->letter) {
> >                         node = node->child[i];
> >                         continue;
> >                 }
> >
> >                 if ((child = new(c)) == NULL) {
> >                         errstr = "new error";
> >                         goto fail;
> >                 }
> >
> >                 /*
> >                 if ((newp = reallocarray(node->child, node->nchild+1,
> > sizeof(*node->child))) == NULL)
> >                         goto fail;
> >                 node->child = newp;
> >                 node->nchild++;
> >
> >                 for (j = node->nchild; j > i; j--)
> >                         node->child[j] = node->child[j-1];
> >                 node->child[j] = child;
> >                 */
> >
> >                 if ((newp = calloc(node->nchild+1, sizeof(*node->child))) 
> > == NULL)
> >                         goto fail;
> >                 for (j = 0; j < i; j++)
> >                         newp[j] = node->child[j];
> >                 newp[j] = child;
> >
> >                 for (j = i+1; j < node->nchild+1; i++, j++)
> >                         newp[j] = node->child[i];
> >                 node->child = newp;
> >                 node->nchild++;
> >
> >                 node = child;
> >         }
> >
> >         node->end = 1;
> >         return 1;
> > fail:
> >         if (errstr)
> >                 warnx("load: %s", errstr);
> >         else
> >                 warn("load");
> >         return 0;
> > }
> >
> > On 8/24/16, Theo de Raadt <[email protected]> wrote:
> >> No way.
> >>
> >> the bug is in your own code, which you didn't show.
> >>
> >>> Hi everyone,
> >>>
> >>> Sorry to trouble the list if this issue turns out to be spurious. I am
> >>> a relatively novice C programmer so it may just be my error. However,
> >>> I have implemented a program two ways: one using reallocarray() and
> >>> the other using calloc().
> >>>
> >>> When I use reallocarray() I get the error "in realloc(): error: use
> >>> after free 0x..." So I recompiled with -g and ran gdb:
> >>>
> >>> Program terminated with signal 6, Aborted.
> >>> Loaded symbols for /home/pmaddams/<REDACTED>
> >>> Reading symbols from /usr/lib/libutil.so.12.1...done.
> >>> Loaded symbols for /usr/lib/libutil.so.12.1
> >>> Reading symbols from /usr/lib/libc.so.84.2...done.
> >>> Loaded symbols for /usr/lib/libc.so.84.2
> >>> Reading symbols from /usr/libexec/ld.so...done.
> >>> Loaded symbols for /usr/libexec/ld.so
> >>> #0  0x00000c01badbc87a in thrkill () at <stdin>:2
> >>> 2       <stdin>: No such file or directory.
> >>>         in <stdin>
> >>>
> >>> The situation is, I have a sorted array of at most 26 elements
> >>> representing the child nodes of a trie. Instead of using a linked list
> >>> I have opted to reallocate the array as a new pointer, shift the top
> >>> elements away from the insertion index, copy the new element into the
> >>> proper location, and assign the new pointer to the old variable.
> >>>
> >>> Using small files this seems to work just fine. However, my goal is to
> >>> read in the entire file from /usr/share/dict/words, 2.4M of text. It
> >>> chokes and dies with the above error. But when I reimplement the
> >>> allocation routine with calloc() it seems to work fine.
> >>>
> >>> What information can I provide to help confirm whether this is a bug
> >>> in the system, or in my own code?
> >>>
> >>> Thanks.
> >>>
> >>
> >>
> >

Reply via email to