|
|
36cfb7 |
From 358ca205cfc9646aefae6572607a0a1363086e51 Mon Sep 17 00:00:00 2001
|
|
|
36cfb7 |
From: Andrea Claudi <aclaudi@redhat.com>
|
|
|
36cfb7 |
Date: Mon, 29 Apr 2019 20:09:13 +0200
|
|
|
36cfb7 |
Subject: [PATCH] Check user supplied interface name lengths
|
|
|
36cfb7 |
|
|
|
36cfb7 |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646
|
|
|
36cfb7 |
Upstream Status: iproute2.git commit 625df645b703d
|
|
|
36cfb7 |
|
|
|
36cfb7 |
commit 625df645b703dc858d54784c35beff64464afae2
|
|
|
36cfb7 |
Author: Phil Sutter <phil@nwl.cc>
|
|
|
36cfb7 |
Date: Mon Oct 2 13:46:37 2017 +0200
|
|
|
36cfb7 |
|
|
|
36cfb7 |
Check user supplied interface name lengths
|
|
|
36cfb7 |
|
|
|
36cfb7 |
The original problem was that something like:
|
|
|
36cfb7 |
|
|
|
36cfb7 |
| strncpy(ifr.ifr_name, *argv, IFNAMSIZ);
|
|
|
36cfb7 |
|
|
|
36cfb7 |
might leave ifr.ifr_name unterminated if length of *argv exceeds
|
|
|
36cfb7 |
IFNAMSIZ. In order to fix this, I thought about replacing all those
|
|
|
36cfb7 |
cases with (equivalent) calls to snprintf() or even introducing
|
|
|
36cfb7 |
strlcpy(). But as Ulrich Drepper correctly pointed out when rejecting
|
|
|
36cfb7 |
the latter from being added to glibc, truncating a string without
|
|
|
36cfb7 |
notifying the user is not to be considered good practice. So let's
|
|
|
36cfb7 |
excercise what he suggested and reject empty, overlong or otherwise
|
|
|
36cfb7 |
invalid interface names right from the start - this way calls to
|
|
|
36cfb7 |
strncpy() like shown above become safe and the user has a chance to
|
|
|
36cfb7 |
reconsider what he was trying to do.
|
|
|
36cfb7 |
|
|
|
36cfb7 |
Note that this doesn't add calls to check_ifname() to all places where
|
|
|
36cfb7 |
user supplied interface name is parsed. In many cases, the interface
|
|
|
36cfb7 |
must exist already and is therefore looked up using ll_name_to_index(),
|
|
|
36cfb7 |
so if_nametoindex() will perform the necessary checks already.
|
|
|
36cfb7 |
|
|
|
36cfb7 |
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
36cfb7 |
---
|
|
|
36cfb7 |
include/utils.h | 2 ++
|
|
|
36cfb7 |
ip/ip6tunnel.c | 3 ++-
|
|
|
36cfb7 |
ip/ipl2tp.c | 4 +++-
|
|
|
36cfb7 |
ip/iplink.c | 31 ++++++++++++-------------------
|
|
|
36cfb7 |
ip/ipmaddr.c | 3 ++-
|
|
|
36cfb7 |
ip/iprule.c | 10 ++++++++--
|
|
|
36cfb7 |
ip/iptunnel.c | 7 ++++++-
|
|
|
36cfb7 |
ip/iptuntap.c | 6 ++++--
|
|
|
36cfb7 |
lib/utils.c | 29 +++++++++++++++++++++++++++++
|
|
|
36cfb7 |
misc/arpd.c | 3 ++-
|
|
|
36cfb7 |
tc/f_flower.c | 2 ++
|
|
|
36cfb7 |
11 files changed, 72 insertions(+), 28 deletions(-)
|
|
|
36cfb7 |
|
|
|
36cfb7 |
diff --git a/include/utils.h b/include/utils.h
|
|
|
36cfb7 |
index d596a6fc10574..0382460136180 100644
|
|
|
36cfb7 |
--- a/include/utils.h
|
|
|
36cfb7 |
+++ b/include/utils.h
|
|
|
36cfb7 |
@@ -145,6 +145,8 @@ void missarg(const char *) __attribute__((noreturn));
|
|
|
36cfb7 |
void invarg(const char *, const char *) __attribute__((noreturn));
|
|
|
36cfb7 |
void duparg(const char *, const char *) __attribute__((noreturn));
|
|
|
36cfb7 |
void duparg2(const char *, const char *) __attribute__((noreturn));
|
|
|
36cfb7 |
+int check_ifname(const char *);
|
|
|
36cfb7 |
+int get_ifname(char *, const char *);
|
|
|
36cfb7 |
int matches(const char *arg, const char *pattern);
|
|
|
36cfb7 |
int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits);
|
|
|
36cfb7 |
|
|
|
36cfb7 |
diff --git a/ip/ip6tunnel.c b/ip/ip6tunnel.c
|
|
|
36cfb7 |
index c12d700e74189..bc44bef7f030c 100644
|
|
|
36cfb7 |
--- a/ip/ip6tunnel.c
|
|
|
36cfb7 |
+++ b/ip/ip6tunnel.c
|
|
|
36cfb7 |
@@ -273,7 +273,8 @@ static int parse_args(int argc, char **argv, int cmd, struct ip6_tnl_parm2 *p)
|
|
|
36cfb7 |
usage();
|
|
|
36cfb7 |
if (p->name[0])
|
|
|
36cfb7 |
duparg2("name", *argv);
|
|
|
36cfb7 |
- strncpy(p->name, *argv, IFNAMSIZ - 1);
|
|
|
36cfb7 |
+ if (get_ifname(p->name, *argv))
|
|
|
36cfb7 |
+ invarg("\"name\" not a valid ifname", *argv);
|
|
|
36cfb7 |
if (cmd == SIOCCHGTUNNEL && count == 0) {
|
|
|
36cfb7 |
struct ip6_tnl_parm2 old_p = {};
|
|
|
36cfb7 |
|
|
|
36cfb7 |
diff --git a/ip/ipl2tp.c b/ip/ipl2tp.c
|
|
|
36cfb7 |
index 742adbe4f9c3a..7c5ed313b186f 100644
|
|
|
36cfb7 |
--- a/ip/ipl2tp.c
|
|
|
36cfb7 |
+++ b/ip/ipl2tp.c
|
|
|
36cfb7 |
@@ -182,7 +182,7 @@ static int create_session(struct l2tp_parm *p)
|
|
|
36cfb7 |
if (p->peer_cookie_len)
|
|
|
36cfb7 |
addattr_l(&req.n, 1024, L2TP_ATTR_PEER_COOKIE,
|
|
|
36cfb7 |
p->peer_cookie, p->peer_cookie_len);
|
|
|
36cfb7 |
- if (p->ifname && p->ifname[0])
|
|
|
36cfb7 |
+ if (p->ifname)
|
|
|
36cfb7 |
addattrstrz(&req.n, 1024, L2TP_ATTR_IFNAME, p->ifname);
|
|
|
36cfb7 |
|
|
|
36cfb7 |
if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
|
|
|
36cfb7 |
@@ -545,6 +545,8 @@ static int parse_args(int argc, char **argv, int cmd, struct l2tp_parm *p)
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
} else if (strcmp(*argv, "name") == 0) {
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
+ if (check_ifname(*argv))
|
|
|
36cfb7 |
+ invarg("\"name\" not a valid ifname", *argv);
|
|
|
36cfb7 |
p->ifname = *argv;
|
|
|
36cfb7 |
} else if (strcmp(*argv, "remote") == 0) {
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
diff --git a/ip/iplink.c b/ip/iplink.c
|
|
|
36cfb7 |
index db5b2c9645ba8..50f1075d94171 100644
|
|
|
36cfb7 |
--- a/ip/iplink.c
|
|
|
36cfb7 |
+++ b/ip/iplink.c
|
|
|
36cfb7 |
@@ -581,6 +581,8 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
|
|
|
36cfb7 |
req->i.ifi_flags &= ~IFF_UP;
|
|
|
36cfb7 |
} else if (strcmp(*argv, "name") == 0) {
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
+ if (check_ifname(*argv))
|
|
|
36cfb7 |
+ invarg("\"name\" not a valid ifname", *argv);
|
|
|
36cfb7 |
*name = *argv;
|
|
|
36cfb7 |
} else if (strcmp(*argv, "index") == 0) {
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
@@ -848,6 +850,8 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
if (*dev)
|
|
|
36cfb7 |
duparg2("dev", *argv);
|
|
|
36cfb7 |
+ if (check_ifname(*argv))
|
|
|
36cfb7 |
+ invarg("\"dev\" not a valid ifname", *argv);
|
|
|
36cfb7 |
*dev = *argv;
|
|
|
36cfb7 |
dev_index = ll_name_to_index(*dev);
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
@@ -870,7 +874,6 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
|
|
|
36cfb7 |
|
|
|
36cfb7 |
static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
|
|
|
36cfb7 |
{
|
|
|
36cfb7 |
- int len;
|
|
|
36cfb7 |
char *dev = NULL;
|
|
|
36cfb7 |
char *name = NULL;
|
|
|
36cfb7 |
char *link = NULL;
|
|
|
36cfb7 |
@@ -960,13 +963,8 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
|
|
|
36cfb7 |
if (name) {
|
|
|
36cfb7 |
- len = strlen(name) + 1;
|
|
|
36cfb7 |
- if (len == 1)
|
|
|
36cfb7 |
- invarg("\"\" is not a valid device identifier\n",
|
|
|
36cfb7 |
- "name");
|
|
|
36cfb7 |
- if (len > IFNAMSIZ)
|
|
|
36cfb7 |
- invarg("\"name\" too long\n", name);
|
|
|
36cfb7 |
- addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, len);
|
|
|
36cfb7 |
+ addattr_l(&req.n, sizeof(req),
|
|
|
36cfb7 |
+ IFLA_IFNAME, name, strlen(name) + 1);
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
|
|
|
36cfb7 |
if (type) {
|
|
|
36cfb7 |
@@ -1016,7 +1014,6 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
|
|
|
36cfb7 |
|
|
|
36cfb7 |
int iplink_get(unsigned int flags, char *name, __u32 filt_mask)
|
|
|
36cfb7 |
{
|
|
|
36cfb7 |
- int len;
|
|
|
36cfb7 |
struct iplink_req req = {
|
|
|
36cfb7 |
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
|
|
|
36cfb7 |
.n.nlmsg_flags = NLM_F_REQUEST | flags,
|
|
|
36cfb7 |
@@ -1026,13 +1023,8 @@ int iplink_get(unsigned int flags, char *name, __u32 filt_mask)
|
|
|
36cfb7 |
struct nlmsghdr *answer;
|
|
|
36cfb7 |
|
|
|
36cfb7 |
if (name) {
|
|
|
36cfb7 |
- len = strlen(name) + 1;
|
|
|
36cfb7 |
- if (len == 1)
|
|
|
36cfb7 |
- invarg("\"\" is not a valid device identifier\n",
|
|
|
36cfb7 |
- "name");
|
|
|
36cfb7 |
- if (len > IFNAMSIZ)
|
|
|
36cfb7 |
- invarg("\"name\" too long\n", name);
|
|
|
36cfb7 |
- addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, len);
|
|
|
36cfb7 |
+ addattr_l(&req.n, sizeof(req),
|
|
|
36cfb7 |
+ IFLA_IFNAME, name, strlen(name) + 1);
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask);
|
|
|
36cfb7 |
|
|
|
36cfb7 |
@@ -1256,6 +1248,8 @@ static int do_set(int argc, char **argv)
|
|
|
36cfb7 |
flags &= ~IFF_UP;
|
|
|
36cfb7 |
} else if (strcmp(*argv, "name") == 0) {
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
+ if (check_ifname(*argv))
|
|
|
36cfb7 |
+ invarg("\"name\" not a valid ifname", *argv);
|
|
|
36cfb7 |
newname = *argv;
|
|
|
36cfb7 |
} else if (matches(*argv, "address") == 0) {
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
@@ -1346,6 +1340,8 @@ static int do_set(int argc, char **argv)
|
|
|
36cfb7 |
|
|
|
36cfb7 |
if (dev)
|
|
|
36cfb7 |
duparg2("dev", *argv);
|
|
|
36cfb7 |
+ if (check_ifname(*argv))
|
|
|
36cfb7 |
+ invarg("\"dev\" not a valid ifname", *argv);
|
|
|
36cfb7 |
dev = *argv;
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
argc--; argv++;
|
|
|
36cfb7 |
@@ -1374,9 +1370,6 @@ static int do_set(int argc, char **argv)
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
|
|
|
36cfb7 |
if (newname && strcmp(dev, newname)) {
|
|
|
36cfb7 |
- if (strlen(newname) == 0)
|
|
|
36cfb7 |
- invarg("\"\" is not a valid device identifier\n",
|
|
|
36cfb7 |
- "name");
|
|
|
36cfb7 |
if (do_changename(dev, newname) < 0)
|
|
|
36cfb7 |
return -1;
|
|
|
36cfb7 |
dev = newname;
|
|
|
36cfb7 |
diff --git a/ip/ipmaddr.c b/ip/ipmaddr.c
|
|
|
36cfb7 |
index 85a69e779563d..5683f6fa830c1 100644
|
|
|
36cfb7 |
--- a/ip/ipmaddr.c
|
|
|
36cfb7 |
+++ b/ip/ipmaddr.c
|
|
|
36cfb7 |
@@ -284,7 +284,8 @@ static int multiaddr_modify(int cmd, int argc, char **argv)
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
if (ifr.ifr_name[0])
|
|
|
36cfb7 |
duparg("dev", *argv);
|
|
|
36cfb7 |
- strncpy(ifr.ifr_name, *argv, IFNAMSIZ);
|
|
|
36cfb7 |
+ if (get_ifname(ifr.ifr_name, *argv))
|
|
|
36cfb7 |
+ invarg("\"dev\" not a valid ifname", *argv);
|
|
|
36cfb7 |
} else {
|
|
|
36cfb7 |
if (matches(*argv, "address") == 0) {
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
diff --git a/ip/iprule.c b/ip/iprule.c
|
|
|
36cfb7 |
index e64b4d7db2815..201d3bdc20427 100644
|
|
|
36cfb7 |
--- a/ip/iprule.c
|
|
|
36cfb7 |
+++ b/ip/iprule.c
|
|
|
36cfb7 |
@@ -472,11 +472,13 @@ static int iprule_list_flush_or_save(int argc, char **argv, int action)
|
|
|
36cfb7 |
} else if (strcmp(*argv, "dev") == 0 ||
|
|
|
36cfb7 |
strcmp(*argv, "iif") == 0) {
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
- strncpy(filter.iif, *argv, IFNAMSIZ);
|
|
|
36cfb7 |
+ if (get_ifname(filter.iif, *argv))
|
|
|
36cfb7 |
+ invarg("\"iif\"/\"dev\" not a valid ifname", *argv);
|
|
|
36cfb7 |
filter.iifmask = 1;
|
|
|
36cfb7 |
} else if (strcmp(*argv, "oif") == 0) {
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
- strncpy(filter.oif, *argv, IFNAMSIZ);
|
|
|
36cfb7 |
+ if (get_ifname(filter.oif, *argv))
|
|
|
36cfb7 |
+ invarg("\"oif\" not a valid ifname", *argv);
|
|
|
36cfb7 |
filter.oifmask = 1;
|
|
|
36cfb7 |
} else if (strcmp(*argv, "l3mdev") == 0) {
|
|
|
36cfb7 |
filter.l3mdev = 1;
|
|
|
36cfb7 |
@@ -695,10 +697,14 @@ static int iprule_modify(int cmd, int argc, char **argv)
|
|
|
36cfb7 |
} else if (strcmp(*argv, "dev") == 0 ||
|
|
|
36cfb7 |
strcmp(*argv, "iif") == 0) {
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
+ if (check_ifname(*argv))
|
|
|
36cfb7 |
+ invarg("\"iif\"/\"dev\" not a valid ifname", *argv);
|
|
|
36cfb7 |
addattr_l(&req.n, sizeof(req), FRA_IFNAME,
|
|
|
36cfb7 |
*argv, strlen(*argv)+1);
|
|
|
36cfb7 |
} else if (strcmp(*argv, "oif") == 0) {
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
+ if (check_ifname(*argv))
|
|
|
36cfb7 |
+ invarg("\"oif\" not a valid ifname", *argv);
|
|
|
36cfb7 |
addattr_l(&req.n, sizeof(req), FRA_OIFNAME,
|
|
|
36cfb7 |
*argv, strlen(*argv)+1);
|
|
|
36cfb7 |
} else if (strcmp(*argv, "l3mdev") == 0) {
|
|
|
36cfb7 |
diff --git a/ip/iptunnel.c b/ip/iptunnel.c
|
|
|
36cfb7 |
index 0acfd0793d3cd..208a1f06ab12f 100644
|
|
|
36cfb7 |
--- a/ip/iptunnel.c
|
|
|
36cfb7 |
+++ b/ip/iptunnel.c
|
|
|
36cfb7 |
@@ -178,7 +178,8 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
|
|
|
36cfb7 |
|
|
|
36cfb7 |
if (p->name[0])
|
|
|
36cfb7 |
duparg2("name", *argv);
|
|
|
36cfb7 |
- strncpy(p->name, *argv, IFNAMSIZ - 1);
|
|
|
36cfb7 |
+ if (get_ifname(p->name, *argv))
|
|
|
36cfb7 |
+ invarg("\"name\" not a valid ifname", *argv);
|
|
|
36cfb7 |
if (cmd == SIOCCHGTUNNEL && count == 0) {
|
|
|
36cfb7 |
struct ip_tunnel_parm old_p = {};
|
|
|
36cfb7 |
|
|
|
36cfb7 |
@@ -487,6 +488,8 @@ static int do_prl(int argc, char **argv)
|
|
|
36cfb7 |
count++;
|
|
|
36cfb7 |
} else if (strcmp(*argv, "dev") == 0) {
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
+ if (check_ifname(*argv))
|
|
|
36cfb7 |
+ invarg("\"dev\" not a valid ifname", *argv);
|
|
|
36cfb7 |
medium = *argv;
|
|
|
36cfb7 |
} else {
|
|
|
36cfb7 |
fprintf(stderr,
|
|
|
36cfb7 |
@@ -534,6 +537,8 @@ static int do_6rd(int argc, char **argv)
|
|
|
36cfb7 |
cmd = SIOCDEL6RD;
|
|
|
36cfb7 |
} else if (strcmp(*argv, "dev") == 0) {
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
+ if (check_ifname(*argv))
|
|
|
36cfb7 |
+ invarg("\"dev\" not a valid ifname", *argv);
|
|
|
36cfb7 |
medium = *argv;
|
|
|
36cfb7 |
} else {
|
|
|
36cfb7 |
fprintf(stderr,
|
|
|
36cfb7 |
diff --git a/ip/iptuntap.c b/ip/iptuntap.c
|
|
|
36cfb7 |
index 451f7f0eac6bb..b46e452f21278 100644
|
|
|
36cfb7 |
--- a/ip/iptuntap.c
|
|
|
36cfb7 |
+++ b/ip/iptuntap.c
|
|
|
36cfb7 |
@@ -176,7 +176,8 @@ static int parse_args(int argc, char **argv,
|
|
|
36cfb7 |
ifr->ifr_flags |= IFF_MULTI_QUEUE;
|
|
|
36cfb7 |
} else if (matches(*argv, "dev") == 0) {
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
- strncpy(ifr->ifr_name, *argv, IFNAMSIZ-1);
|
|
|
36cfb7 |
+ if (get_ifname(ifr->ifr_name, *argv))
|
|
|
36cfb7 |
+ invarg("\"dev\" not a valid ifname", *argv);
|
|
|
36cfb7 |
} else {
|
|
|
36cfb7 |
if (matches(*argv, "name") == 0) {
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
@@ -184,7 +185,8 @@ static int parse_args(int argc, char **argv,
|
|
|
36cfb7 |
usage();
|
|
|
36cfb7 |
if (ifr->ifr_name[0])
|
|
|
36cfb7 |
duparg2("name", *argv);
|
|
|
36cfb7 |
- strncpy(ifr->ifr_name, *argv, IFNAMSIZ);
|
|
|
36cfb7 |
+ if (get_ifname(ifr->ifr_name, *argv))
|
|
|
36cfb7 |
+ invarg("\"name\" not a valid ifname", *argv);
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
count++;
|
|
|
36cfb7 |
argc--; argv++;
|
|
|
36cfb7 |
diff --git a/lib/utils.c b/lib/utils.c
|
|
|
36cfb7 |
index 228d97bfe5e9b..0c56f0b478f23 100644
|
|
|
36cfb7 |
--- a/lib/utils.c
|
|
|
36cfb7 |
+++ b/lib/utils.c
|
|
|
36cfb7 |
@@ -20,6 +20,7 @@
|
|
|
36cfb7 |
#include <sys/socket.h>
|
|
|
36cfb7 |
#include <netinet/in.h>
|
|
|
36cfb7 |
#include <string.h>
|
|
|
36cfb7 |
+#include <ctype.h>
|
|
|
36cfb7 |
#include <netdb.h>
|
|
|
36cfb7 |
#include <arpa/inet.h>
|
|
|
36cfb7 |
#include <asm/types.h>
|
|
|
36cfb7 |
@@ -697,6 +698,34 @@ void duparg2(const char *key, const char *arg)
|
|
|
36cfb7 |
exit(-1);
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
|
|
|
36cfb7 |
+int check_ifname(const char *name)
|
|
|
36cfb7 |
+{
|
|
|
36cfb7 |
+ /* These checks mimic kernel checks in dev_valid_name */
|
|
|
36cfb7 |
+ if (*name == '\0')
|
|
|
36cfb7 |
+ return -1;
|
|
|
36cfb7 |
+ if (strlen(name) >= IFNAMSIZ)
|
|
|
36cfb7 |
+ return -1;
|
|
|
36cfb7 |
+
|
|
|
36cfb7 |
+ while (*name) {
|
|
|
36cfb7 |
+ if (*name == '/' || isspace(*name))
|
|
|
36cfb7 |
+ return -1;
|
|
|
36cfb7 |
+ ++name;
|
|
|
36cfb7 |
+ }
|
|
|
36cfb7 |
+ return 0;
|
|
|
36cfb7 |
+}
|
|
|
36cfb7 |
+
|
|
|
36cfb7 |
+/* buf is assumed to be IFNAMSIZ */
|
|
|
36cfb7 |
+int get_ifname(char *buf, const char *name)
|
|
|
36cfb7 |
+{
|
|
|
36cfb7 |
+ int ret;
|
|
|
36cfb7 |
+
|
|
|
36cfb7 |
+ ret = check_ifname(name);
|
|
|
36cfb7 |
+ if (ret == 0)
|
|
|
36cfb7 |
+ strncpy(buf, name, IFNAMSIZ);
|
|
|
36cfb7 |
+
|
|
|
36cfb7 |
+ return ret;
|
|
|
36cfb7 |
+}
|
|
|
36cfb7 |
+
|
|
|
36cfb7 |
int matches(const char *cmd, const char *pattern)
|
|
|
36cfb7 |
{
|
|
|
36cfb7 |
int len = strlen(cmd);
|
|
|
36cfb7 |
diff --git a/misc/arpd.c b/misc/arpd.c
|
|
|
36cfb7 |
index c9d86475e5995..67d86b67957b8 100644
|
|
|
36cfb7 |
--- a/misc/arpd.c
|
|
|
36cfb7 |
+++ b/misc/arpd.c
|
|
|
36cfb7 |
@@ -662,7 +662,8 @@ int main(int argc, char **argv)
|
|
|
36cfb7 |
struct ifreq ifr = {};
|
|
|
36cfb7 |
|
|
|
36cfb7 |
for (i = 0; i < ifnum; i++) {
|
|
|
36cfb7 |
- strncpy(ifr.ifr_name, ifnames[i], IFNAMSIZ);
|
|
|
36cfb7 |
+ if (get_ifname(ifr.ifr_name, ifnames[i]))
|
|
|
36cfb7 |
+ invarg("not a valid ifname", ifnames[i]);
|
|
|
36cfb7 |
if (ioctl(udp_sock, SIOCGIFINDEX, &ifr)) {
|
|
|
36cfb7 |
perror("ioctl(SIOCGIFINDEX)");
|
|
|
36cfb7 |
exit(-1);
|
|
|
36cfb7 |
diff --git a/tc/f_flower.c b/tc/f_flower.c
|
|
|
36cfb7 |
index 34249254603ff..f3f8d3427c761 100644
|
|
|
36cfb7 |
--- a/tc/f_flower.c
|
|
|
36cfb7 |
+++ b/tc/f_flower.c
|
|
|
36cfb7 |
@@ -643,6 +643,8 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
|
|
|
36cfb7 |
flags |= TCA_CLS_FLAGS_SKIP_SW;
|
|
|
36cfb7 |
} else if (matches(*argv, "indev") == 0) {
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
+ if (check_ifname(*argv))
|
|
|
36cfb7 |
+ invarg("\"indev\" not a valid ifname", *argv);
|
|
|
36cfb7 |
addattrstrz(n, MAX_MSG, TCA_FLOWER_INDEV, *argv);
|
|
|
36cfb7 |
} else if (matches(*argv, "vlan_id") == 0) {
|
|
|
36cfb7 |
__u16 vid;
|
|
|
36cfb7 |
--
|
|
|
36cfb7 |
2.20.1
|
|
|
36cfb7 |
|