platform: add and use nm_utils_ifname_cpy() helper
Coverity complains rightly about "strncpy (dst, ifname, IFNAMSIZ)" because it might leave @dst non-NULL-terminated, in case @ifname is too long (which already would be a bug in the first place). Replace the strcpy() uses by a new helper nm_utils_ifname_cpy() that asserts against valid arguments.
This commit is contained in:
@@ -27,8 +27,11 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "nm-lldp-listener.h"
|
||||
|
||||
#include "test-common.h"
|
||||
|
||||
#include "nm-test-utils.h"
|
||||
|
||||
typedef struct {
|
||||
int ifindex;
|
||||
int fd;
|
||||
@@ -48,7 +51,7 @@ fixture_setup (test_fixture *fixture, gconstpointer user_data)
|
||||
g_assert (fd >= 0);
|
||||
|
||||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
|
||||
strncpy (ifr.ifr_name, TEST_IFNAME, IFNAMSIZ);
|
||||
nm_utils_ifname_cpy (ifr.ifr_name, TEST_IFNAME);
|
||||
g_assert (ioctl (fd, TUNSETIFF, &ifr) >= 0);
|
||||
|
||||
/* Bring the interface up */
|
||||
|
@@ -2942,4 +2942,15 @@ nm_utils_parse_debug_string (const char *string,
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
nm_utils_ifname_cpy (char *dst, const char *name)
|
||||
{
|
||||
g_return_if_fail (dst);
|
||||
g_return_if_fail (name && name[0]);
|
||||
|
||||
nm_assert (nm_utils_iface_valid_name (name));
|
||||
|
||||
if (g_strlcpy (dst, name, IFNAMSIZ) >= IFNAMSIZ)
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
|
@@ -412,4 +412,6 @@ guint nm_utils_parse_debug_string (const char *string,
|
||||
const GDebugKey *keys,
|
||||
guint nkeys);
|
||||
|
||||
void nm_utils_ifname_cpy (char *dst, const char *name);
|
||||
|
||||
#endif /* __NM_CORE_UTILS_H__ */
|
||||
|
@@ -4835,7 +4835,7 @@ tun_add (NMPlatform *platform, const char *name, gboolean tap,
|
||||
if (fd < 0)
|
||||
return FALSE;
|
||||
|
||||
strncpy (ifr.ifr_name, name, IFNAMSIZ);
|
||||
nm_utils_ifname_cpy (ifr.ifr_name, name);
|
||||
ifr.ifr_flags = tap ? IFF_TAP : IFF_TUN;
|
||||
|
||||
if (!pi)
|
||||
|
@@ -56,7 +56,7 @@ ethtool_get (const char *name, gpointer edata)
|
||||
nm_assert (strlen (name) < IFNAMSIZ);
|
||||
|
||||
memset (&ifr, 0, sizeof (ifr));
|
||||
strcpy (ifr.ifr_name, name);
|
||||
nm_utils_ifname_cpy (ifr.ifr_name, name);
|
||||
ifr.ifr_data = edata;
|
||||
|
||||
fd = socket (PF_INET, SOCK_DGRAM, 0);
|
||||
@@ -344,7 +344,7 @@ nmp_utils_mii_supports_carrier_detect (const char *ifname)
|
||||
}
|
||||
|
||||
memset (&ifr, 0, sizeof (struct ifreq));
|
||||
strncpy (ifr.ifr_name, ifname, IFNAMSIZ);
|
||||
nm_utils_ifname_cpy (ifr.ifr_name, ifname);
|
||||
|
||||
errno = 0;
|
||||
if (ioctl (fd, SIOCGMIIPHY, &ifr) < 0) {
|
||||
@@ -513,13 +513,14 @@ gboolean
|
||||
nmp_utils_device_exists (const char *name)
|
||||
{
|
||||
#define SYS_CLASS_NET "/sys/class/net/"
|
||||
char sysdir[NM_STRLEN (SYS_CLASS_NET) + IFNAMSIZ] = SYS_CLASS_NET;
|
||||
char sysdir[NM_STRLEN (SYS_CLASS_NET) + IFNAMSIZ];
|
||||
|
||||
if ( !name
|
||||
|| strlen (name) >= IFNAMSIZ
|
||||
|| !nm_utils_is_valid_path_component (name))
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
||||
strcpy (&sysdir[NM_STRLEN (SYS_CLASS_NET)], name);
|
||||
memcpy (sysdir, SYS_CLASS_NET, NM_STRLEN (SYS_CLASS_NET));
|
||||
nm_utils_ifname_cpy (&sysdir[NM_STRLEN (SYS_CLASS_NET)], name);
|
||||
return g_file_test (sysdir, G_FILE_TEST_EXISTS);
|
||||
}
|
||||
|
@@ -18,12 +18,11 @@
|
||||
* Copyright (C) 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-platform-utils.h"
|
||||
#include "nm-default.h"
|
||||
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
#include "nm-linux-platform.h"
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nm-test-utils.h"
|
||||
|
||||
|
@@ -101,7 +101,7 @@ wifi_wext_get_mode (WifiData *data)
|
||||
struct iwreq wrq;
|
||||
|
||||
memset (&wrq, 0, sizeof (struct iwreq));
|
||||
g_strlcpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ);
|
||||
nm_utils_ifname_cpy (wrq.ifr_name, wext->parent.iface);
|
||||
|
||||
if (ioctl (wext->fd, SIOCGIWMODE, &wrq) < 0) {
|
||||
if (errno != ENODEV) {
|
||||
@@ -150,7 +150,7 @@ wifi_wext_set_mode (WifiData *data, const NM80211Mode mode)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_strlcpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ);
|
||||
nm_utils_ifname_cpy (wrq.ifr_name, wext->parent.iface);
|
||||
if (ioctl (wext->fd, SIOCSIWMODE, &wrq) < 0) {
|
||||
if (errno != ENODEV) {
|
||||
nm_log_err (LOGD_HW | LOGD_WIFI, "(%s): error setting mode %d",
|
||||
@@ -174,7 +174,7 @@ wifi_wext_set_powersave (WifiData *data, guint32 powersave)
|
||||
} else
|
||||
wrq.u.power.disabled = 1;
|
||||
|
||||
g_strlcpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ);
|
||||
nm_utils_ifname_cpy (wrq.ifr_name, wext->parent.iface);
|
||||
if (ioctl (wext->fd, SIOCSIWPOWER, &wrq) < 0) {
|
||||
if (errno != ENODEV) {
|
||||
nm_log_err (LOGD_HW | LOGD_WIFI, "(%s): error setting powersave %" G_GUINT32_FORMAT,
|
||||
@@ -193,7 +193,7 @@ wifi_wext_get_freq (WifiData *data)
|
||||
struct iwreq wrq;
|
||||
|
||||
memset (&wrq, 0, sizeof (struct iwreq));
|
||||
g_strlcpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ);
|
||||
nm_utils_ifname_cpy (wrq.ifr_name, wext->parent.iface);
|
||||
if (ioctl (wext->fd, SIOCGIWFREQ, &wrq) < 0) {
|
||||
nm_log_warn (LOGD_HW | LOGD_WIFI,
|
||||
"(%s): error getting frequency: %s",
|
||||
@@ -227,7 +227,7 @@ wifi_wext_get_bssid (WifiData *data, guint8 *out_bssid)
|
||||
struct iwreq wrq;
|
||||
|
||||
memset (&wrq, 0, sizeof (wrq));
|
||||
g_strlcpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ);
|
||||
nm_utils_ifname_cpy (wrq.ifr_name, wext->parent.iface);
|
||||
if (ioctl (wext->fd, SIOCGIWAP, &wrq) < 0) {
|
||||
nm_log_warn (LOGD_HW | LOGD_WIFI,
|
||||
"(%s): error getting associated BSSID: %s",
|
||||
@@ -246,7 +246,7 @@ wifi_wext_get_rate (WifiData *data)
|
||||
int err;
|
||||
|
||||
memset (&wrq, 0, sizeof (wrq));
|
||||
g_strlcpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ);
|
||||
nm_utils_ifname_cpy (wrq.ifr_name, wext->parent.iface);
|
||||
err = ioctl (wext->fd, SIOCGIWRATE, &wrq);
|
||||
return ((err == 0) ? wrq.u.bitrate.value / 1000 : 0);
|
||||
}
|
||||
@@ -356,7 +356,7 @@ wifi_wext_get_qual (WifiData *data)
|
||||
wrq.u.data.pointer = &stats;
|
||||
wrq.u.data.length = sizeof (stats);
|
||||
wrq.u.data.flags = 1; /* Clear updated flag */
|
||||
g_strlcpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ);
|
||||
nm_utils_ifname_cpy (wrq.ifr_name, wext->parent.iface);
|
||||
|
||||
if (ioctl (wext->fd, SIOCGIWSTATS, &wrq) < 0) {
|
||||
nm_log_warn (LOGD_HW | LOGD_WIFI,
|
||||
@@ -393,7 +393,7 @@ wifi_wext_set_mesh_channel (WifiData *data, guint32 channel)
|
||||
struct iwreq wrq;
|
||||
|
||||
memset (&wrq, 0, sizeof (struct iwreq));
|
||||
g_strlcpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ);
|
||||
nm_utils_ifname_cpy (wrq.ifr_name, wext->parent.iface);
|
||||
|
||||
if (channel > 0) {
|
||||
wrq.u.freq.flags = IW_FREQ_FIXED;
|
||||
@@ -425,7 +425,7 @@ wifi_wext_set_mesh_ssid (WifiData *data, const guint8 *ssid, gsize len)
|
||||
wrq.u.essid.length = len;
|
||||
wrq.u.essid.flags = (len > 0) ? 1 : 0; /* 1=enable SSID, 0=disable/any */
|
||||
|
||||
g_strlcpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ);
|
||||
nm_utils_ifname_cpy (wrq.ifr_name, wext->parent.iface);
|
||||
if (ioctl (wext->fd, SIOCSIWESSID, &wrq) == 0)
|
||||
return TRUE;
|
||||
|
||||
@@ -448,7 +448,7 @@ wext_can_scan (WifiDataWext *wext)
|
||||
struct iwreq wrq;
|
||||
|
||||
memset (&wrq, 0, sizeof (struct iwreq));
|
||||
g_strlcpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ);
|
||||
nm_utils_ifname_cpy (wrq.ifr_name, wext->parent.iface);
|
||||
if (ioctl (wext->fd, SIOCSIWSCAN, &wrq) < 0) {
|
||||
if (errno == EOPNOTSUPP)
|
||||
return FALSE;
|
||||
@@ -466,7 +466,7 @@ wext_get_range (WifiDataWext *wext,
|
||||
struct iwreq wrq;
|
||||
|
||||
memset (&wrq, 0, sizeof (struct iwreq));
|
||||
g_strlcpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ);
|
||||
nm_utils_ifname_cpy (wrq.ifr_name, wext->parent.iface);
|
||||
wrq.u.data.pointer = (caddr_t) range;
|
||||
wrq.u.data.length = sizeof (struct iw_range);
|
||||
|
||||
@@ -666,7 +666,7 @@ wifi_wext_is_wifi (const char *iface)
|
||||
|
||||
fd = socket (PF_INET, SOCK_DGRAM, 0);
|
||||
if (fd >= 0) {
|
||||
g_strlcpy (iwr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
|
||||
nm_utils_ifname_cpy (iwr.ifr_ifrn.ifrn_name, iface);
|
||||
if (ioctl (fd, SIOCGIWNAME, &iwr) == 0)
|
||||
is_wifi = TRUE;
|
||||
close (fd);
|
||||
|
Reference in New Issue
Block a user