malloc/free mismatches in tradspool.c
WATANABE Katsuhiro
katsu at watanabe.name
Mon Oct 25 07:49:34 UTC 2004
I've found some dangerous code portions in terms of
memory management in inn-2.4.1/storage/tradspool.c.
I'd be pleased if you can confirm following points
and fix them.
[1] Referring free-ed memory contents.
In tradspool_next(), you can find following code:
1059 priv = *(PRIV_TRADSPOOL *) article->private;
1060 free(article->private);
1061 free((void*)article);
1062 if (priv.artbase != NULL) {
1063 if (priv.mmapped)
1064 munmap(priv.artbase, priv.artlen);
1065 else
1066 free(priv.artbase);
1067 }
But at line 1062, structure priv(= article->private) has been
free-ed already (at 1060). So theoretically speaking, it can
happen to have garbage memory contents when its member is
referred.
I know it works most cases but I believe the following code
would be cleaner and much safer :
priv = *(PRIV_TRADSPOOL *) article->private;
if (priv.artbase != NULL) {
if (priv.mmapped)
munmap(priv.artbase, priv.artlen);
else
free(priv.artbase);
}
free(article->private);
free((void*)article);
[2] Free-ing not allocated memory.
You can find many code ideoms in tradspool.c saying:
xrefs = CrackXref(...);
...
for (i = 0 ; i < numxrefs; ++i) free(xrefs[i]);
free(xrefs);
But the array xrefs is allocated as just ONE memory
chunk, not as an array of allocated memories in
CrackXref(). So freeing xref's each elements does not
make any sense.
I think, the for loop free-ing each elements should be
eliminated. You can find these for loop
in tradspool_store()
at line 592, 616, 626, 640, 660, 698, 709 and 721.
in tradspool_cancel()
at line 989.
in tradspool_next()
at line 1157.
Also, in case CrackXref() returns NULL or 0-element array,
there are some differences in the way the code handles the
irregular case. Like:
(A) Just free xrefs.
581 if ((xrefs = CrackXref(xrefhdr, &numxrefs)) == NULL || numxrefs == 0) {
584 if (xrefs != NULL)
585 free(xrefs);
(B) Do nothing.
959 if ((xrefs = CrackXref(xrefhdr, &numxrefs)) == NULL || numxrefs == 0) {
960 free(path);
961 tradspool_freearticle(article);
962 SMseterror(SMERR_UNDEFINED, NULL);
963 return false;
(C) Free xrefs and free its elements also.
1136 if ((xrefs = CrackXref(xrefhdr, &numxrefs)) == NULL || numxr
efs == 0) {
1137 art->len = 0;
/* Then falling through the if clause and it is handled later ... */
1157 for (i = 0 ; i < numxrefs ; ++i) free(xrefs[i]);
1158 free(xrefs);
But I'am not sure which is the best way to handle the exceptional
case and how to fix that contradictions.
--
WATANABE Katsuhiro
More information about the inn-bugs
mailing list