@@ -162,11 +162,22 @@ static inline u32 tcf_auto_prio(struct tcf_proto *tp)
162162 return TC_H_MAJ (first );
163163}
164164
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+
165173static bool tcf_proto_is_unlocked (const char * kind )
166174{
167175 const struct tcf_proto_ops * ops ;
168176 bool ret ;
169177
178+ if (strlen (kind ) == 0 )
179+ return false;
180+
170181 ops = tcf_proto_lookup_ops (kind , false, NULL );
171182 /* On error return false to take rtnl lock. Proto lookup/create
172183 * 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,
18431854{
18441855 struct net * net = sock_net (skb -> sk );
18451856 struct nlattr * tca [TCA_MAX + 1 ];
1857+ char name [IFNAMSIZ ];
18461858 struct tcmsg * t ;
18471859 u32 protocol ;
18481860 u32 prio ;
@@ -1899,13 +1911,19 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
18991911 if (err )
19001912 return err ;
19011913
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+
19021920 /* Take rtnl mutex if rtnl_held was set to true on previous iteration,
19031921 * block is shared (no qdisc found), qdisc is not unlocked, classifier
19041922 * type is not specified, classifier is not unlocked.
19051923 */
19061924 if (rtnl_held ||
19071925 (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 )) {
19091927 rtnl_held = true;
19101928 rtnl_lock ();
19111929 }
@@ -2063,6 +2081,7 @@ static int tc_del_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
20632081{
20642082 struct net * net = sock_net (skb -> sk );
20652083 struct nlattr * tca [TCA_MAX + 1 ];
2084+ char name [IFNAMSIZ ];
20662085 struct tcmsg * t ;
20672086 u32 protocol ;
20682087 u32 prio ;
@@ -2102,13 +2121,18 @@ static int tc_del_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
21022121 if (err )
21032122 return err ;
21042123
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+ }
21052129 /* Take rtnl mutex if flushing whole chain, block is shared (no qdisc
21062130 * found), qdisc is not unlocked, classifier type is not specified,
21072131 * classifier is not unlocked.
21082132 */
21092133 if (!prio ||
21102134 (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 )) {
21122136 rtnl_held = true;
21132137 rtnl_lock ();
21142138 }
@@ -2216,6 +2240,7 @@ static int tc_get_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
22162240{
22172241 struct net * net = sock_net (skb -> sk );
22182242 struct nlattr * tca [TCA_MAX + 1 ];
2243+ char name [IFNAMSIZ ];
22192244 struct tcmsg * t ;
22202245 u32 protocol ;
22212246 u32 prio ;
@@ -2252,12 +2277,17 @@ static int tc_get_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
22522277 if (err )
22532278 return err ;
22542279
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+ }
22552285 /* Take rtnl mutex if block is shared (no qdisc found), qdisc is not
22562286 * unlocked, classifier type is not specified, classifier is not
22572287 * unlocked.
22582288 */
22592289 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 )) {
22612291 rtnl_held = true;
22622292 rtnl_lock ();
22632293 }
0 commit comments