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

net: ip6_gre: Distribute switch variables for initialization

Variables declared in a switch statement before any case statements
cannot be automatically initialized with compiler instrumentation (as
they are not part of any execution flow). With GCC's proposed automatic
stack variable initialization feature, this triggers a warning (and they
don't get initialized). Clang's automatic stack variable initialization
(via CONFIG_INIT_STACK_ALL=y) doesn't throw a warning, but it also
doesn't initialize such variables[1]. Note that these warnings (or silent
skipping) happen before the dead-store elimination optimization phase,
so even when the automatic initializations are later elided in favor of
direct initializations, the warnings remain.

To avoid these problems, move such variables into the "case" where
they're used or lift them up into the main function body.

net/ipv6/ip6_gre.c: In function ‘ip6gre_err’:
net/ipv6/ip6_gre.c:440:32: warning: statement will never be executed [-Wswitch-unreachable]
440 | struct ipv6_tlv_tnl_enc_lim *tel;
| ^~~

net/ipv6/ip6_tunnel.c: In function ‘ip6_tnl_err’:
net/ipv6/ip6_tunnel.c:520:32: warning: statement will never be executed [-Wswitch-unreachable]
520 | struct ipv6_tlv_tnl_enc_lim *tel;
| ^~~

[1] https://bugs.llvm.org/show_bug.cgi?id=44916

Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Kees Cook and committed by
David S. Miller
46d30cb1 161d1792

+14 -7
+5 -3
net/ipv6/ip6_gre.c
··· 437 437 return -ENOENT; 438 438 439 439 switch (type) { 440 - struct ipv6_tlv_tnl_enc_lim *tel; 441 - __u32 teli; 442 440 case ICMPV6_DEST_UNREACH: 443 441 net_dbg_ratelimited("%s: Path to destination invalid or inactive!\n", 444 442 t->parms.name); ··· 450 452 break; 451 453 } 452 454 return 0; 453 - case ICMPV6_PARAMPROB: 455 + case ICMPV6_PARAMPROB: { 456 + struct ipv6_tlv_tnl_enc_lim *tel; 457 + __u32 teli; 458 + 454 459 teli = 0; 455 460 if (code == ICMPV6_HDR_FIELD) 456 461 teli = ip6_tnl_parse_tlv_enc_lim(skb, skb->data); ··· 469 468 t->parms.name); 470 469 } 471 470 return 0; 471 + } 472 472 case ICMPV6_PKT_TOOBIG: 473 473 ip6_update_pmtu(skb, net, info, 0, 0, sock_net_uid(net, NULL)); 474 474 return 0;
+9 -4
net/ipv6/ip6_tunnel.c
··· 517 517 err = 0; 518 518 519 519 switch (*type) { 520 - struct ipv6_tlv_tnl_enc_lim *tel; 521 - __u32 mtu, teli; 522 520 case ICMPV6_DEST_UNREACH: 523 521 net_dbg_ratelimited("%s: Path to destination invalid or inactive!\n", 524 522 t->parms.name); ··· 529 531 rel_msg = 1; 530 532 } 531 533 break; 532 - case ICMPV6_PARAMPROB: 534 + case ICMPV6_PARAMPROB: { 535 + struct ipv6_tlv_tnl_enc_lim *tel; 536 + __u32 teli; 537 + 533 538 teli = 0; 534 539 if ((*code) == ICMPV6_HDR_FIELD) 535 540 teli = ip6_tnl_parse_tlv_enc_lim(skb, skb->data); ··· 549 548 t->parms.name); 550 549 } 551 550 break; 552 - case ICMPV6_PKT_TOOBIG: 551 + } 552 + case ICMPV6_PKT_TOOBIG: { 553 + __u32 mtu; 554 + 553 555 ip6_update_pmtu(skb, net, htonl(*info), 0, 0, 554 556 sock_net_uid(net, NULL)); 555 557 mtu = *info - offset; ··· 566 562 rel_msg = 1; 567 563 } 568 564 break; 565 + } 569 566 case NDISC_REDIRECT: 570 567 ip6_redirect(skb, net, skb->dev->ifindex, 0, 571 568 sock_net_uid(net, NULL));