Skip to content
Permalink
Browse files

net: Check device driver API pointer

It is possible that the device driver API pointer is null.
For example if the device driver returns an error, the device
code will make the API pointer NULL so that the API would not
be used. This can cause errors in networking code where we
typically do not check the NULL value.

Fixes #15003

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
  • Loading branch information...
jukkar committed Apr 15, 2019
1 parent 9a6e301 commit 9a6bbbfb698860d38c63534b8e4b7c958fd72f63
@@ -217,7 +217,10 @@ static inline void init_iface(struct net_if *iface)
{
const struct net_if_api *api = net_if_get_device(iface)->driver_api;

NET_ASSERT(api && api->init);
if (!api || !api->init) {
NET_ERR("Iface %p driver API init NULL", iface);
return;
}

NET_DBG("On iface %p", iface);

@@ -33,6 +33,10 @@ static inline int canbus_send(struct net_if *iface, struct net_pkt *pkt)
const struct canbus_api *api = net_if_get_device(iface)->driver_api;
int ret;

if (!api) {
return -ENOENT;
}

ret = api->send(net_if_get_device(iface), pkt);
if (!ret) {
ret = net_pkt_get_len(pkt);
@@ -32,6 +32,10 @@ static inline int dummy_send(struct net_if *iface, struct net_pkt *pkt)
const struct dummy_api *api = net_if_get_device(iface)->driver_api;
int ret;

if (!api) {
return -ENOENT;
}

ret = api->send(net_if_get_device(iface), pkt);
if (!ret) {
ret = net_pkt_get_len(pkt);
@@ -528,6 +528,11 @@ static int ethernet_send(struct net_if *iface, struct net_pkt *pkt)
u16_t ptype;
int ret;

if (!api) {
ret = -ENOENT;
goto error;
}

if (IS_ENABLED(CONFIG_NET_IPV4) &&
net_pkt_family(pkt) == AF_INET) {
struct net_pkt *tmp;
@@ -621,6 +626,10 @@ static inline int ethernet_enable(struct net_if *iface, bool state)
const struct ethernet_api *eth =
net_if_get_device(iface)->driver_api;

if (!eth) {
return -ENOENT;
}

if (!state) {
net_arp_clear_cache(iface);

@@ -781,6 +790,10 @@ int net_eth_vlan_enable(struct net_if *iface, u16_t tag)
struct ethernet_vlan *vlan;
int i;

if (!eth) {
return -ENOENT;
}

if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) {
return -EINVAL;
}
@@ -838,6 +851,10 @@ int net_eth_vlan_disable(struct net_if *iface, u16_t tag)
net_if_get_device(iface)->driver_api;
struct ethernet_vlan *vlan;

if (!eth) {
return -ENOENT;
}

if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) {
return -EINVAL;
}
@@ -932,6 +949,10 @@ struct device *net_eth_get_ptp_clock(struct net_if *iface)
struct device *dev = net_if_get_device(iface);
const struct ethernet_api *api = dev->driver_api;

if (!api) {
return NULL;
}

if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) {
return NULL;
}
@@ -18,6 +18,10 @@ static inline bool is_hw_caps_supported(struct device *dev,
{
const struct ethernet_api *api = dev->driver_api;

if (!api) {
return false;
}

return !!(api->get_capabilities(dev) & caps);
}

@@ -31,6 +35,10 @@ static int ethernet_set_config(u32_t mgmt_request,
struct ethernet_config config = { 0 };
enum ethernet_config_type type;

if (!api) {
return -ENOENT;
}

if (!api->set_config) {
return -ENOTSUP;
}
@@ -174,6 +182,10 @@ static int ethernet_get_config(u32_t mgmt_request,
int ret = 0;
enum ethernet_config_type type;

if (!api) {
return -ENOENT;
}

if (!api->get_config) {
return -ENOTSUP;
}
@@ -31,7 +31,7 @@ static int eth_stats_get(u32_t mgmt_request, struct net_if *iface,
}

eth = net_if_get_device(iface)->driver_api;
if (eth->get_stats == NULL) {
if (eth == NULL || eth->get_stats == NULL) {
return -ENOENT;
}

@@ -20,6 +20,10 @@ enum ieee802154_hw_caps ieee802154_get_hw_capabilities(struct net_if *iface)
const struct ieee802154_radio_api *radio =
net_if_get_device(iface)->driver_api;

if (!radio) {
return 0;
}

return radio->get_capabilities(net_if_get_device(iface));
}

@@ -28,6 +32,10 @@ static inline int ieee802154_cca(struct net_if *iface)
const struct ieee802154_radio_api *radio =
net_if_get_device(iface)->driver_api;

if (!radio) {
return -ENOENT;
}

return radio->cca(net_if_get_device(iface));
}

@@ -36,6 +44,10 @@ static inline int ieee802154_set_channel(struct net_if *iface, u16_t channel)
const struct ieee802154_radio_api *radio =
net_if_get_device(iface)->driver_api;

if (!radio) {
return -ENOENT;
}

return radio->set_channel(net_if_get_device(iface), channel);
}

@@ -44,6 +56,10 @@ static inline int ieee802154_set_tx_power(struct net_if *iface, s16_t dbm)
const struct ieee802154_radio_api *radio =
net_if_get_device(iface)->driver_api;

if (!radio) {
return -ENOENT;
}

return radio->set_txpower(net_if_get_device(iface), dbm);
}

@@ -53,6 +69,10 @@ static inline int ieee802154_tx(struct net_if *iface,
const struct ieee802154_radio_api *radio =
net_if_get_device(iface)->driver_api;

if (!radio) {
return -ENOENT;
}

return radio->tx(net_if_get_device(iface), pkt, buf);
}

@@ -61,6 +81,10 @@ static inline int ieee802154_start(struct net_if *iface)
const struct ieee802154_radio_api *radio =
net_if_get_device(iface)->driver_api;

if (!radio) {
return -ENOENT;
}

return radio->start(net_if_get_device(iface));
}

@@ -69,6 +93,10 @@ static inline int ieee802154_stop(struct net_if *iface)
const struct ieee802154_radio_api *radio =
net_if_get_device(iface)->driver_api;

if (!radio) {
return -ENOENT;
}

return radio->stop(net_if_get_device(iface));
}

@@ -78,8 +106,8 @@ static inline void ieee802154_filter_ieee_addr(struct net_if *iface,
const struct ieee802154_radio_api *radio =
net_if_get_device(iface)->driver_api;

if (radio->get_capabilities(net_if_get_device(iface)) &
IEEE802154_HW_FILTER) {
if (radio && (radio->get_capabilities(net_if_get_device(iface)) &
IEEE802154_HW_FILTER)) {
struct ieee802154_filter filter;

filter.ieee_addr = ieee_addr;
@@ -98,8 +126,8 @@ static inline void ieee802154_filter_short_addr(struct net_if *iface,
const struct ieee802154_radio_api *radio =
net_if_get_device(iface)->driver_api;

if (radio->get_capabilities(net_if_get_device(iface)) &
IEEE802154_HW_FILTER) {
if (radio && (radio->get_capabilities(net_if_get_device(iface)) &
IEEE802154_HW_FILTER)) {
struct ieee802154_filter filter;

filter.short_addr = short_addr;
@@ -118,8 +146,8 @@ static inline void ieee802154_filter_pan_id(struct net_if *iface,
const struct ieee802154_radio_api *radio =
net_if_get_device(iface)->driver_api;

if (radio->get_capabilities(net_if_get_device(iface)) &
IEEE802154_HW_FILTER) {
if (radio && (radio->get_capabilities(net_if_get_device(iface)) &
IEEE802154_HW_FILTER)) {
struct ieee802154_filter filter;

filter.pan_id = pan_id;
@@ -138,8 +166,8 @@ static inline void ieee802154_filter_src_ieee_addr(struct net_if *iface,
const struct ieee802154_radio_api *radio =
net_if_get_device(iface)->driver_api;

if (radio->get_capabilities(net_if_get_device(iface)) &
IEEE802154_HW_FILTER) {
if (radio && (radio->get_capabilities(net_if_get_device(iface)) &
IEEE802154_HW_FILTER)) {
struct ieee802154_filter filter;

filter.ieee_addr = ieee_addr;
@@ -158,8 +186,8 @@ static inline void ieee802154_filter_src_short_addr(struct net_if *iface,
const struct ieee802154_radio_api *radio =
net_if_get_device(iface)->driver_api;

if (radio->get_capabilities(net_if_get_device(iface)) &
IEEE802154_HW_FILTER) {
if (radio && (radio->get_capabilities(net_if_get_device(iface)) &
IEEE802154_HW_FILTER)) {
struct ieee802154_filter filter;

filter.short_addr = short_addr;
@@ -178,8 +206,8 @@ static inline void ieee802154_remove_src_ieee_addr(struct net_if *iface,
const struct ieee802154_radio_api *radio =
net_if_get_device(iface)->driver_api;

if (radio->get_capabilities(net_if_get_device(iface)) &
IEEE802154_HW_FILTER) {
if (radio && (radio->get_capabilities(net_if_get_device(iface)) &
IEEE802154_HW_FILTER)) {
struct ieee802154_filter filter;

filter.ieee_addr = ieee_addr;
@@ -198,8 +226,8 @@ static inline void ieee802154_remove_src_short_addr(struct net_if *iface,
const struct ieee802154_radio_api *radio =
net_if_get_device(iface)->driver_api;

if (radio->get_capabilities(net_if_get_device(iface)) &
IEEE802154_HW_FILTER) {
if (radio && (radio->get_capabilities(net_if_get_device(iface)) &
IEEE802154_HW_FILTER)) {
struct ieee802154_filter filter;

filter.short_addr = short_addr;
@@ -223,6 +251,10 @@ static inline bool ieee802154_verify_channel(struct net_if *iface,
const struct ieee802154_radio_api *radio =
net_if_get_device(iface)->driver_api;

if (!radio) {
return false;
}

if (radio->get_capabilities(net_if_get_device(iface)) &
IEEE802154_HW_SUB_GHZ) {
if (channel >
@@ -73,6 +73,9 @@ void platformRadioInit(void)
__ASSERT_NO_MSG(radio_dev != NULL);

radio_api = (struct ieee802154_radio_api *)radio_dev->driver_api;
if (!radio_api) {
return;
}

__ASSERT(radio_api->get_capabilities(radio_dev)
& IEEE802154_HW_TX_RX_ACK,
@@ -354,7 +354,7 @@ static int can_sock_getsockopt_vmeth(void *obj, int level, int optname,
dev = net_if_get_device(iface);
api = dev->driver_api;

if (!api->getsockopt) {
if (!api || !api->getsockopt) {
errno = ENOTSUP;
return -1;
}
@@ -392,7 +392,7 @@ static int can_sock_setsockopt_vmeth(void *obj, int level, int optname,
dev = net_if_get_device(iface);
api = dev->driver_api;

if (!api->setsockopt) {
if (!api || !api->setsockopt) {
errno = ENOTSUP;
return -1;
}

0 comments on commit 9a6bbbf

Please sign in to comment.
You can’t perform that action at this time.