Commit 9b90aca9 authored by Hangyu Hua's avatar Hangyu Hua Committed by David S. Miller

net: ethernet: bcmasp: fix possible OOB write in bcmasp_netfilt_get_all_active()

rule_locs is allocated in ethtool_get_rxnfc and the size is determined by
rule_cnt from user space. So rule_cnt needs to be check before using
rule_locs to avoid OOB writing or NULL pointer dereference.

Fixes: c5d511c4 ("net: bcmasp: Add support for wake on net filters")
Signed-off-by: default avatarHangyu Hua <hbh25y@gmail.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fa60b816
...@@ -528,13 +528,16 @@ void bcmasp_netfilt_suspend(struct bcmasp_intf *intf) ...@@ -528,13 +528,16 @@ void bcmasp_netfilt_suspend(struct bcmasp_intf *intf)
ASP_RX_FILTER_BLK_CTRL); ASP_RX_FILTER_BLK_CTRL);
} }
void bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs, int bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs,
u32 *rule_cnt) u32 *rule_cnt)
{ {
struct bcmasp_priv *priv = intf->parent; struct bcmasp_priv *priv = intf->parent;
int j = 0, i; int j = 0, i;
for (i = 0; i < NUM_NET_FILTERS; i++) { for (i = 0; i < NUM_NET_FILTERS; i++) {
if (j == *rule_cnt)
return -EMSGSIZE;
if (!priv->net_filters[i].claimed || if (!priv->net_filters[i].claimed ||
priv->net_filters[i].port != intf->port) priv->net_filters[i].port != intf->port)
continue; continue;
...@@ -548,6 +551,8 @@ void bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs, ...@@ -548,6 +551,8 @@ void bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs,
} }
*rule_cnt = j; *rule_cnt = j;
return 0;
} }
int bcmasp_netfilt_get_active(struct bcmasp_intf *intf) int bcmasp_netfilt_get_active(struct bcmasp_intf *intf)
......
...@@ -577,8 +577,8 @@ void bcmasp_netfilt_release(struct bcmasp_intf *intf, ...@@ -577,8 +577,8 @@ void bcmasp_netfilt_release(struct bcmasp_intf *intf,
int bcmasp_netfilt_get_active(struct bcmasp_intf *intf); int bcmasp_netfilt_get_active(struct bcmasp_intf *intf);
void bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs, int bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs,
u32 *rule_cnt); u32 *rule_cnt);
void bcmasp_netfilt_suspend(struct bcmasp_intf *intf); void bcmasp_netfilt_suspend(struct bcmasp_intf *intf);
......
...@@ -335,7 +335,7 @@ static int bcmasp_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, ...@@ -335,7 +335,7 @@ static int bcmasp_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
err = bcmasp_flow_get(intf, cmd); err = bcmasp_flow_get(intf, cmd);
break; break;
case ETHTOOL_GRXCLSRLALL: case ETHTOOL_GRXCLSRLALL:
bcmasp_netfilt_get_all_active(intf, rule_locs, &cmd->rule_cnt); err = bcmasp_netfilt_get_all_active(intf, rule_locs, &cmd->rule_cnt);
cmd->data = NUM_NET_FILTERS; cmd->data = NUM_NET_FILTERS;
break; break;
default: default:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment