I found this code on git and wanted to use it, but someone made a comment about a security bug in it. I don't seem to identify it:
int32_t read_arrbuff(FILE *f, uint32_t *arrmap) {
int32_t i = 0, n_map;
fread(&n_map, sizeof(n_map), 1, f);
if (n_map > 256)
return -1;
while (n_map--) {
fread(&arrmap[i++], sizeof(uint32_t), 1, f);
}
return n_map;
}
Taken in isolation, the problems include:
fis not NULL.arrmapis not NULL.fread()was successful.fread()was successful.-1, regardless of whether anything worked or failed.Which of those are security problems? At some levels, all of them. In some contexts, you could assume that
fandarrmapare legitimate without checking. Not checking that the reads are successful, especially the first, is a serious problem. The negative values forn_mapwould be a serious issue. Claiming success when every read failed would be a problem.When the loop completes,
n_mapis set to-1(it was zero before the post-decrement). So, you return -1 on failure or success. That's not helpful. It should almost certainly return the value ofn_mapthat was read from file, so the caller can tell how many values are in the array.It is usually best not to hard code a size limit like
256into the program. The interface should include the array size and you should check against the passed array size.Working to the original interface, you could use:
You can debate whether the unilateral exits imposed by
err_syserr()are appropriate. (The declarations and source for theerr_*()functions is instderr.handstderr.c, and is available from GitHub.)An alternative version taking the maximum array size from a function parameter is:
This version reports a specific error and returns on error. It makes semi-appropriate assertions on entry (the 256 limit is not necessarily appropriate, but is consistent with the original code).
The output is unexciting (and the same from both):