CodeHawk-C crash on invalid astr attribute parameter index
Summary
While analyzing SPEC CPU 2017 538.imagick_r, CodeHawk-C crashed during
project linking before analysis rounds started. The crash occurs when a parsed
star attribute parameter (astr) references an attrparam-table index that does
not exist in the current file dictionary.
The immediate crash was:
chc.util.IndexedTable.IndexedTableError:
Unable to retrieve item 5 from table attrparam-table (size: 4)
The stack goes through:
CLinker.link_varinfos
CGlobalDeclarations.make_global_varinfo
CTyp.strip_attributes
CAttributes.__str__
CAttribute.__str__
CAttrStar.__str__
CAttrStar.param
CDictionary.get_attrparam
Reproducer
Use repros/imagick-invalid-astr-attrparam.c:
#include <stdio.h>
#include <stdlib.h>
void *repro_alloc(size_t n) {
return malloc(n);
}
int main(void) {
void *p = repro_alloc(16);
puts(p == NULL ? "null" : "ok");
free(p);
return 0;
}
Analyze this file as a small CodeHawk-C project with ordinary glibc headers.
The same malformed astr dictionary shape is observed in the imagick parse
results for files such as:
magick/quantum/quantum_cdict.xml:
attrparam-table has max index 4
attrparam ix=2 has t="astr" and a="5"
Several other imagick files have astr entries whose argument is clearly not a
valid local attrparam-table index, e.g. a="431" with max attrparam index 5.
Cause
CAttrStar.param assumes that args[0] is always an attrparam-table index. In
these parsed GNU/glibc attribute cases that assumption is false, so stringifying
type attributes during strip_attributes can chase an invalid dictionary index.
There is also a small type mismatch in CAttrStar.__str__: it compares
self.index to self.args[0], but self.index is an integer and
self.args[0] is a string. The self-reference case therefore never matches.
Minimal Fix
Treat self-referential or invalid astr arguments as opaque star attributes
instead of chasing the bad dictionary index. This is conservative for analysis:
the exact GNU attribute expression is not needed for PTSan/CodeHawk memory
proof obligations in imagick, and dropping precision in this attribute string
avoids blocking project analysis.
The local patch:
CodeHawk-C/chc/app/CAttributes.py
changes CAttrStar.param to catch IndexedTableError and return self, and
fixes __str__ to compare self.index with int(self.args[0]).
imagick-invalid-astr-attrparam.c
CodeHawk-C crash on invalid
astrattribute parameter indexSummary
While analyzing SPEC CPU 2017
538.imagick_r, CodeHawk-C crashed duringproject linking before analysis rounds started. The crash occurs when a parsed
star attribute parameter (
astr) references an attrparam-table index that doesnot exist in the current file dictionary.
The immediate crash was:
The stack goes through:
Reproducer
Use
repros/imagick-invalid-astr-attrparam.c:Analyze this file as a small CodeHawk-C project with ordinary glibc headers.
The same malformed
astrdictionary shape is observed in the imagick parseresults for files such as:
Several other imagick files have
astrentries whose argument is clearly not avalid local attrparam-table index, e.g.
a="431"with max attrparam index5.Cause
CAttrStar.paramassumes thatargs[0]is always an attrparam-table index. Inthese parsed GNU/glibc attribute cases that assumption is false, so stringifying
type attributes during
strip_attributescan chase an invalid dictionary index.There is also a small type mismatch in
CAttrStar.__str__: it comparesself.indextoself.args[0], butself.indexis an integer andself.args[0]is a string. The self-reference case therefore never matches.Minimal Fix
Treat self-referential or invalid
astrarguments as opaque star attributesinstead of chasing the bad dictionary index. This is conservative for analysis:
the exact GNU attribute expression is not needed for PTSan/CodeHawk memory
proof obligations in imagick, and dropping precision in this attribute string
avoids blocking project analysis.
The local patch:
changes
CAttrStar.paramto catchIndexedTableErrorand returnself, andfixes
__str__to compareself.indexwithint(self.args[0]).imagick-invalid-astr-attrparam.c