net_find_af_name: do not assume that address families are consecutive

The network_families array is automatically built from AF_NAMES, which is
extracted from the defines in <bits/socket.h>. The code assumes that
network_families is indexed by the AF defines. However, since the
defines are sparse, and the gaps in the array are not packed with
zeroes, the array is shorter than expected, and the indexing is wrong.

When this function was written, the network families that were
covered might well have been consecutive, but this is no longer true:
there's a gap between AF_LLC (26) and AF_CAN (29). In addition,
the code that parses <sys/socket.h> does not recognise AF_DECnet (12)
due to the lower-case letters, leading to a gap betwen AF_ROSE (11)
and AF_NETBEUI (13).

This assumption caused a crash in our testing while parsing the rule
"network raw".

[smcv: split out from a larger patch, added commit message]
Reviewed-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
This commit is contained in:
Philip Withnall 2015-02-27 16:20:31 +00:00 committed by Simon McVittie
parent c913956554
commit 097c520293

View file

@ -342,10 +342,17 @@ int net_find_af_val(const char *af)
const char *net_find_af_name(unsigned int af)
{
int i;
if (af < 0 || af > get_af_max())
return NULL;
return network_families[af];
for (i = 0; i < sizeof(network_mappings) / sizeof(*network_mappings); i++) {
if (network_mappings[i].family == af)
return network_mappings[i].family_name;
}
return NULL;
}
void __debug_network(unsigned int *array, const char *name)
@ -375,7 +382,7 @@ void __debug_network(unsigned int *array, const char *name)
for (i = 0; i < af_max; i++) {
if (array[i]) {
const char *fam = network_families[i];
const char *fam = net_find_af_name(i);
if (fam)
printf("%s ", fam);
else