Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lwtunnel: check erspan options before allocating tun_info

As Jakub suggested on another patch, it's better to do the check
on erspan options before allocating memory.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Xin Long and committed by
David S. Miller
1841b982 7b6a70f7

+16 -8
+16 -8
net/ipv4/ip_tunnel_core.c
··· 321 321 { 322 322 struct nlattr *tb[LWTUNNEL_IP_OPT_ERSPAN_MAX + 1]; 323 323 int err; 324 + u8 ver; 324 325 325 326 err = nla_parse_nested(tb, LWTUNNEL_IP_OPT_ERSPAN_MAX, attr, 326 327 erspan_opt_policy, extack); ··· 331 330 if (!tb[LWTUNNEL_IP_OPT_ERSPAN_VER]) 332 331 return -EINVAL; 333 332 333 + ver = nla_get_u8(tb[LWTUNNEL_IP_OPT_ERSPAN_VER]); 334 + if (ver == 1) { 335 + if (!tb[LWTUNNEL_IP_OPT_ERSPAN_INDEX]) 336 + return -EINVAL; 337 + } else if (ver == 2) { 338 + if (!tb[LWTUNNEL_IP_OPT_ERSPAN_DIR] || 339 + !tb[LWTUNNEL_IP_OPT_ERSPAN_HWID]) 340 + return -EINVAL; 341 + } else { 342 + return -EINVAL; 343 + } 344 + 334 345 if (info) { 335 346 struct erspan_metadata *md = 336 347 ip_tunnel_info_opts(info) + opts_len; 337 348 338 - attr = tb[LWTUNNEL_IP_OPT_ERSPAN_VER]; 339 - md->version = nla_get_u8(attr); 340 - 341 - if (md->version == 1 && tb[LWTUNNEL_IP_OPT_ERSPAN_INDEX]) { 349 + md->version = ver; 350 + if (ver == 1) { 342 351 attr = tb[LWTUNNEL_IP_OPT_ERSPAN_INDEX]; 343 352 md->u.index = nla_get_be32(attr); 344 - } else if (md->version == 2 && tb[LWTUNNEL_IP_OPT_ERSPAN_DIR] && 345 - tb[LWTUNNEL_IP_OPT_ERSPAN_HWID]) { 353 + } else { 346 354 attr = tb[LWTUNNEL_IP_OPT_ERSPAN_DIR]; 347 355 md->u.md2.dir = nla_get_u8(attr); 348 356 attr = tb[LWTUNNEL_IP_OPT_ERSPAN_HWID]; 349 357 set_hwid(&md->u.md2, nla_get_u8(attr)); 350 - } else { 351 - return -EINVAL; 352 358 } 353 359 354 360 info->key.tun_flags |= TUNNEL_ERSPAN_OPT;