@@ -162,11 +162,22 @@ static inline u32 tcf_auto_prio(struct tcf_proto *tp)
162
162
return TC_H_MAJ (first );
163
163
}
164
164
165
+ static bool tcf_proto_check_kind (struct nlattr * kind , char * name )
166
+ {
167
+ if (kind )
168
+ return nla_strlcpy (name , kind , IFNAMSIZ ) >= IFNAMSIZ ;
169
+ memset (name , 0 , IFNAMSIZ );
170
+ return false;
171
+ }
172
+
165
173
static bool tcf_proto_is_unlocked (const char * kind )
166
174
{
167
175
const struct tcf_proto_ops * ops ;
168
176
bool ret ;
169
177
178
+ if (strlen (kind ) == 0 )
179
+ return false;
180
+
170
181
ops = tcf_proto_lookup_ops (kind , false, NULL );
171
182
/* On error return false to take rtnl lock. Proto lookup/create
172
183
* functions will perform lookup again and properly handle errors.
@@ -1843,6 +1854,7 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
1843
1854
{
1844
1855
struct net * net = sock_net (skb -> sk );
1845
1856
struct nlattr * tca [TCA_MAX + 1 ];
1857
+ char name [IFNAMSIZ ];
1846
1858
struct tcmsg * t ;
1847
1859
u32 protocol ;
1848
1860
u32 prio ;
@@ -1899,13 +1911,19 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
1899
1911
if (err )
1900
1912
return err ;
1901
1913
1914
+ if (tcf_proto_check_kind (tca [TCA_KIND ], name )) {
1915
+ NL_SET_ERR_MSG (extack , "Specified TC filter name too long" );
1916
+ err = - EINVAL ;
1917
+ goto errout ;
1918
+ }
1919
+
1902
1920
/* Take rtnl mutex if rtnl_held was set to true on previous iteration,
1903
1921
* block is shared (no qdisc found), qdisc is not unlocked, classifier
1904
1922
* type is not specified, classifier is not unlocked.
1905
1923
*/
1906
1924
if (rtnl_held ||
1907
1925
(q && !(q -> ops -> cl_ops -> flags & QDISC_CLASS_OPS_DOIT_UNLOCKED )) ||
1908
- !tca [ TCA_KIND ] || ! tcf_proto_is_unlocked (nla_data ( tca [ TCA_KIND ]) )) {
1926
+ !tcf_proto_is_unlocked (name )) {
1909
1927
rtnl_held = true;
1910
1928
rtnl_lock ();
1911
1929
}
@@ -2063,6 +2081,7 @@ static int tc_del_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
2063
2081
{
2064
2082
struct net * net = sock_net (skb -> sk );
2065
2083
struct nlattr * tca [TCA_MAX + 1 ];
2084
+ char name [IFNAMSIZ ];
2066
2085
struct tcmsg * t ;
2067
2086
u32 protocol ;
2068
2087
u32 prio ;
@@ -2102,13 +2121,18 @@ static int tc_del_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
2102
2121
if (err )
2103
2122
return err ;
2104
2123
2124
+ if (tcf_proto_check_kind (tca [TCA_KIND ], name )) {
2125
+ NL_SET_ERR_MSG (extack , "Specified TC filter name too long" );
2126
+ err = - EINVAL ;
2127
+ goto errout ;
2128
+ }
2105
2129
/* Take rtnl mutex if flushing whole chain, block is shared (no qdisc
2106
2130
* found), qdisc is not unlocked, classifier type is not specified,
2107
2131
* classifier is not unlocked.
2108
2132
*/
2109
2133
if (!prio ||
2110
2134
(q && !(q -> ops -> cl_ops -> flags & QDISC_CLASS_OPS_DOIT_UNLOCKED )) ||
2111
- !tca [ TCA_KIND ] || ! tcf_proto_is_unlocked (nla_data ( tca [ TCA_KIND ]) )) {
2135
+ !tcf_proto_is_unlocked (name )) {
2112
2136
rtnl_held = true;
2113
2137
rtnl_lock ();
2114
2138
}
@@ -2216,6 +2240,7 @@ static int tc_get_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
2216
2240
{
2217
2241
struct net * net = sock_net (skb -> sk );
2218
2242
struct nlattr * tca [TCA_MAX + 1 ];
2243
+ char name [IFNAMSIZ ];
2219
2244
struct tcmsg * t ;
2220
2245
u32 protocol ;
2221
2246
u32 prio ;
@@ -2252,12 +2277,17 @@ static int tc_get_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
2252
2277
if (err )
2253
2278
return err ;
2254
2279
2280
+ if (tcf_proto_check_kind (tca [TCA_KIND ], name )) {
2281
+ NL_SET_ERR_MSG (extack , "Specified TC filter name too long" );
2282
+ err = - EINVAL ;
2283
+ goto errout ;
2284
+ }
2255
2285
/* Take rtnl mutex if block is shared (no qdisc found), qdisc is not
2256
2286
* unlocked, classifier type is not specified, classifier is not
2257
2287
* unlocked.
2258
2288
*/
2259
2289
if ((q && !(q -> ops -> cl_ops -> flags & QDISC_CLASS_OPS_DOIT_UNLOCKED )) ||
2260
- !tca [ TCA_KIND ] || ! tcf_proto_is_unlocked (nla_data ( tca [ TCA_KIND ]) )) {
2290
+ !tcf_proto_is_unlocked (name )) {
2261
2291
rtnl_held = true;
2262
2292
rtnl_lock ();
2263
2293
}
0 commit comments