Skip to content

Commit

Permalink
nfp: prevent theoretical buffer overrun in nfp_eth_read_ports
Browse files Browse the repository at this point in the history
Prevent theoretical buffer overrun by returning an error if
the number of entries returned by the firmware does not match those
present.

Also use a common handling error path.

Found by inspection.

Signed-off-by: Simon Horman <simon.horman@netronome.com>
Tested-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Simon Horman authored and David S. Miller committed Mar 10, 2017
1 parent b9dcf88 commit 5692dbb
Showing 1 changed file with 20 additions and 14 deletions.
34 changes: 20 additions & 14 deletions drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,7 @@ __nfp_eth_read_ports(struct nfp_cpp *cpp, struct nfp_nsp *nsp)
{
struct eth_table_entry *entries;
struct nfp_eth_table *table;
unsigned int cnt;
int i, j, ret;
int i, j, ret, cnt = 0;

entries = kzalloc(NSP_ETH_TABLE_SIZE, GFP_KERNEL);
if (!entries)
Expand All @@ -201,24 +200,27 @@ __nfp_eth_read_ports(struct nfp_cpp *cpp, struct nfp_nsp *nsp)
ret = nfp_nsp_read_eth_table(nsp, entries, NSP_ETH_TABLE_SIZE);
if (ret < 0) {
nfp_err(cpp, "reading port table failed %d\n", ret);
kfree(entries);
return NULL;
goto err;
}

/* Some versions of flash will give us 0 instead of port count */
cnt = ret;
if (!cnt) {
for (i = 0; i < NSP_ETH_MAX_COUNT; i++)
if (entries[i].port & NSP_ETH_PORT_LANES_MASK)
cnt++;
for (i = 0; i < NSP_ETH_MAX_COUNT; i++)
if (entries[i].port & NSP_ETH_PORT_LANES_MASK)
cnt++;

/* Some versions of flash will give us 0 instead of port count.
* For those that give a port count, verify it against the value
* calculated above.
*/
if (ret && ret != cnt) {
nfp_err(cpp, "table entry count reported (%d) does not match entries present (%d)\n",
ret, cnt);
goto err;
}

table = kzalloc(sizeof(*table) +
sizeof(struct nfp_eth_table_port) * cnt, GFP_KERNEL);
if (!table) {
kfree(entries);
return NULL;
}
if (!table)
goto err;

table->count = cnt;
for (i = 0, j = 0; i < NSP_ETH_MAX_COUNT; i++)
Expand All @@ -231,6 +233,10 @@ __nfp_eth_read_ports(struct nfp_cpp *cpp, struct nfp_nsp *nsp)
kfree(entries);

return table;

err:
kfree(entries);
return NULL;
}

/**
Expand Down

0 comments on commit 5692dbb

Please sign in to comment.