net: if: Make sure only allowed threads can access syscalls

Make sure that only those threads that have been granted access
to net_if objects, can call the functions that modify net_if data.

The CONFIG_NET_IF_USERSPACE_ACCESS config option is also removed
as it is no longer needed after this change.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2020-06-18 19:05:12 +03:00 committed by Anas Nashif
commit 336bcfa471
4 changed files with 87 additions and 47 deletions

View file

@ -57,6 +57,7 @@ Removed APIs in this release
* The deprecated ``MACRO_MAP`` macro has been removed from the * The deprecated ``MACRO_MAP`` macro has been removed from the
:ref:`util_api`. Use ``FOR_EACH`` instead. :ref:`util_api`. Use ``FOR_EACH`` instead.
* The CONFIG_NET_IF_USERSPACE_ACCESS is removed as it is no longer needed.
Stable API changes in this release Stable API changes in this release
================================== ==================================

View file

@ -1930,11 +1930,14 @@ bool net_if_need_calc_tx_checksum(struct net_if *iface);
/** /**
* @brief Get interface according to index * @brief Get interface according to index
* *
* @details This is a syscall only to provide access to the object for purposes
* of assigning permissions.
*
* @param index Interface index * @param index Interface index
* *
* @return Pointer to interface or NULL if not found. * @return Pointer to interface or NULL if not found.
*/ */
struct net_if *net_if_get_by_index(int index); __syscall struct net_if *net_if_get_by_index(int index);
/** /**
* @brief Get interface index according to pointer * @brief Get interface index according to pointer

View file

@ -611,14 +611,6 @@ config NET_HEADERS_ALWAYS_CONTIGUOUS
NET_BUF_FIXED_DATA_SIZE enabled and NET_BUF_DATA_SIZE of 128 for NET_BUF_FIXED_DATA_SIZE enabled and NET_BUF_DATA_SIZE of 128 for
instance. instance.
config NET_IF_USERSPACE_ACCESS
bool "Allow userspace app to manipulate network interface"
depends on USERSPACE
help
Only enable this if you want a userspace application to manipulate
network interface. Currently this is limited to add or remove
IP addresses. By default this is not allowed.
choice choice
prompt "Default Network Interface" prompt "Default Network Interface"
default NET_DEFAULT_IF_FIRST default NET_DEFAULT_IF_FIRST

View file

@ -123,6 +123,46 @@ static sys_slist_t timestamp_callbacks;
#define debug_check_packet(...) #define debug_check_packet(...)
#endif /* CONFIG_NET_IF_LOG_LEVEL >= LOG_LEVEL_DBG */ #endif /* CONFIG_NET_IF_LOG_LEVEL >= LOG_LEVEL_DBG */
struct net_if *z_impl_net_if_get_by_index(int index)
{
if (index <= 0) {
return NULL;
}
if (&_net_if_list_start[index - 1] >= _net_if_list_end) {
NET_DBG("Index %d is too large", index);
return NULL;
}
return &_net_if_list_start[index - 1];
}
#ifdef CONFIG_USERSPACE
struct net_if *z_vrfy_net_if_get_by_index(int index)
{
struct net_if *iface;
struct z_object *zo;
int ret;
iface = net_if_get_by_index(index);
if (!iface) {
return NULL;
}
zo = z_object_find(iface);
ret = z_object_validate(zo, K_OBJ_NET_IF, _OBJ_INIT_TRUE);
if (ret != 0) {
z_dump_object_error(ret, iface, zo, K_OBJ_NET_IF);
return NULL;
}
return iface;
}
#include <syscalls/net_if_get_by_index_mrsh.c>
#endif
static inline void net_context_send_cb(struct net_context *context, static inline void net_context_send_cb(struct net_context *context,
int status) int status)
{ {
@ -1569,8 +1609,13 @@ bool z_vrfy_net_if_ipv6_addr_add_by_index(int index,
enum net_addr_type addr_type, enum net_addr_type addr_type,
uint32_t vlifetime) uint32_t vlifetime)
{ {
#if defined(CONFIG_NET_IF_USERSPACE_ACCESS)
struct in6_addr addr_v6; struct in6_addr addr_v6;
struct net_if *iface;
iface = z_vrfy_net_if_get_by_index(index);
if (!iface) {
return false;
}
Z_OOPS(z_user_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6))); Z_OOPS(z_user_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6)));
@ -1578,10 +1623,8 @@ bool z_vrfy_net_if_ipv6_addr_add_by_index(int index,
&addr_v6, &addr_v6,
addr_type, addr_type,
vlifetime); vlifetime);
#else
return false;
#endif /* CONFIG_NET_IF_USERSPACE_ACCESS */
} }
#include <syscalls/net_if_ipv6_addr_add_by_index_mrsh.c> #include <syscalls/net_if_ipv6_addr_add_by_index_mrsh.c>
#endif /* CONFIG_USERSPACE */ #endif /* CONFIG_USERSPACE */
@ -1602,16 +1645,19 @@ bool z_impl_net_if_ipv6_addr_rm_by_index(int index,
bool z_vrfy_net_if_ipv6_addr_rm_by_index(int index, bool z_vrfy_net_if_ipv6_addr_rm_by_index(int index,
const struct in6_addr *addr) const struct in6_addr *addr)
{ {
#if defined(CONFIG_NET_IF_USERSPACE_ACCESS)
struct in6_addr addr_v6; struct in6_addr addr_v6;
struct net_if *iface;
iface = z_vrfy_net_if_get_by_index(index);
if (!iface) {
return false;
}
Z_OOPS(z_user_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6))); Z_OOPS(z_user_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6)));
return z_impl_net_if_ipv6_addr_rm_by_index(index, &addr_v6); return z_impl_net_if_ipv6_addr_rm_by_index(index, &addr_v6);
#else
return false;
#endif /* CONFIG_NET_IF_USERSPACE_ACCESS */
} }
#include <syscalls/net_if_ipv6_addr_rm_by_index_mrsh.c> #include <syscalls/net_if_ipv6_addr_rm_by_index_mrsh.c>
#endif /* CONFIG_USERSPACE */ #endif /* CONFIG_USERSPACE */
@ -2903,17 +2949,20 @@ bool z_impl_net_if_ipv4_set_netmask_by_index(int index,
bool z_vrfy_net_if_ipv4_set_netmask_by_index(int index, bool z_vrfy_net_if_ipv4_set_netmask_by_index(int index,
const struct in_addr *netmask) const struct in_addr *netmask)
{ {
#if defined(CONFIG_NET_IF_USERSPACE_ACCESS)
struct in_addr netmask_addr; struct in_addr netmask_addr;
struct net_if *iface;
iface = z_vrfy_net_if_get_by_index(index);
if (!iface) {
return false;
}
Z_OOPS(z_user_from_copy(&netmask_addr, (void *)netmask, Z_OOPS(z_user_from_copy(&netmask_addr, (void *)netmask,
sizeof(netmask_addr))); sizeof(netmask_addr)));
return z_impl_net_if_ipv4_set_netmask_by_index(index, &netmask_addr); return z_impl_net_if_ipv4_set_netmask_by_index(index, &netmask_addr);
#else
return false;
#endif
} }
#include <syscalls/net_if_ipv4_set_netmask_by_index_mrsh.c> #include <syscalls/net_if_ipv4_set_netmask_by_index_mrsh.c>
#endif /* CONFIG_USERSPACE */ #endif /* CONFIG_USERSPACE */
@ -2949,16 +2998,19 @@ bool z_impl_net_if_ipv4_set_gw_by_index(int index,
bool z_vrfy_net_if_ipv4_set_gw_by_index(int index, bool z_vrfy_net_if_ipv4_set_gw_by_index(int index,
const struct in_addr *gw) const struct in_addr *gw)
{ {
#if defined(CONFIG_NET_IF_USERSPACE_ACCESS)
struct in_addr gw_addr; struct in_addr gw_addr;
struct net_if *iface;
iface = z_vrfy_net_if_get_by_index(index);
if (!iface) {
return false;
}
Z_OOPS(z_user_from_copy(&gw_addr, (void *)gw, sizeof(gw_addr))); Z_OOPS(z_user_from_copy(&gw_addr, (void *)gw, sizeof(gw_addr)));
return z_impl_net_if_ipv4_set_gw_by_index(index, &gw_addr); return z_impl_net_if_ipv4_set_gw_by_index(index, &gw_addr);
#else
return false;
#endif
} }
#include <syscalls/net_if_ipv4_set_gw_by_index_mrsh.c> #include <syscalls/net_if_ipv4_set_gw_by_index_mrsh.c>
#endif /* CONFIG_USERSPACE */ #endif /* CONFIG_USERSPACE */
@ -3108,8 +3160,13 @@ bool z_vrfy_net_if_ipv4_addr_add_by_index(int index,
enum net_addr_type addr_type, enum net_addr_type addr_type,
uint32_t vlifetime) uint32_t vlifetime)
{ {
#if defined(CONFIG_NET_IF_USERSPACE_ACCESS)
struct in_addr addr_v4; struct in_addr addr_v4;
struct net_if *iface;
iface = z_vrfy_net_if_get_by_index(index);
if (!iface) {
return false;
}
Z_OOPS(z_user_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4))); Z_OOPS(z_user_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4)));
@ -3117,10 +3174,8 @@ bool z_vrfy_net_if_ipv4_addr_add_by_index(int index,
&addr_v4, &addr_v4,
addr_type, addr_type,
vlifetime); vlifetime);
#else
return false;
#endif /* CONFIG_NET_IF_USERSPACE_ACCESS */
} }
#include <syscalls/net_if_ipv4_addr_add_by_index_mrsh.c> #include <syscalls/net_if_ipv4_addr_add_by_index_mrsh.c>
#endif /* CONFIG_USERSPACE */ #endif /* CONFIG_USERSPACE */
@ -3141,16 +3196,19 @@ bool z_impl_net_if_ipv4_addr_rm_by_index(int index,
bool z_vrfy_net_if_ipv4_addr_rm_by_index(int index, bool z_vrfy_net_if_ipv4_addr_rm_by_index(int index,
const struct in_addr *addr) const struct in_addr *addr)
{ {
#if defined(CONFIG_NET_IF_USERSPACE_ACCESS)
struct in_addr addr_v4; struct in_addr addr_v4;
struct net_if *iface;
iface = z_vrfy_net_if_get_by_index(index);
if (!iface) {
return false;
}
Z_OOPS(z_user_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4))); Z_OOPS(z_user_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4)));
return (uint32_t)z_impl_net_if_ipv4_addr_rm_by_index(index, &addr_v4); return (uint32_t)z_impl_net_if_ipv4_addr_rm_by_index(index, &addr_v4);
#else
return false;
#endif /* CONFIG_NET_IF_USERSPACE_ACCESS */
} }
#include <syscalls/net_if_ipv4_addr_rm_by_index_mrsh.c> #include <syscalls/net_if_ipv4_addr_rm_by_index_mrsh.c>
#endif /* CONFIG_USERSPACE */ #endif /* CONFIG_USERSPACE */
@ -3421,20 +3479,6 @@ bool net_if_need_calc_rx_checksum(struct net_if *iface)
return need_calc_checksum(iface, ETHERNET_HW_RX_CHKSUM_OFFLOAD); return need_calc_checksum(iface, ETHERNET_HW_RX_CHKSUM_OFFLOAD);
} }
struct net_if *net_if_get_by_index(int index)
{
if (index <= 0) {
return NULL;
}
if (&_net_if_list_start[index - 1] >= _net_if_list_end) {
NET_DBG("Index %d is too large", index);
return NULL;
}
return &_net_if_list_start[index - 1];
}
int net_if_get_by_iface(struct net_if *iface) int net_if_get_by_iface(struct net_if *iface)
{ {
if (!(iface >= _net_if_list_start && iface < _net_if_list_end)) { if (!(iface >= _net_if_list_start && iface < _net_if_list_end)) {