net: seg6: initialize induction variable to first valid array index
Fixes the following warnings observed when building CONFIG_IPV6_SEG6_LWTUNNEL=y with clang: net/ipv6/seg6_local.o: warning: objtool: seg6_local_fill_encap() falls through to next function seg6_local_get_encap_size() net/ipv6/seg6_local.o: warning: objtool: seg6_local_cmp_encap() falls through to next function input_action_end() LLVM can fully unroll loops in seg6_local_get_encap_size() and seg6_local_cmp_encap(). One issue in those loops is that the induction variable is initialized to 0. The loop iterates over members of seg6_action_params, a global array of struct seg6_action_param calling their put() function pointer members. seg6_action_param uses an array initializer to initialize SEG6_LOCAL_SRH and later elements, which is the third enumeration of an anonymous union. The guard `if (attrs & SEG6_F_ATTR(i))` may prevent this from being called at runtime, but it would still be UB for `seg6_action_params[0]->put` to be called; the unrolled loop will make the initial iterations unreachable, which LLVM will later rotate to fallthrough to the next function. Make this more obvious that this cannot happen to the compiler by initializing the loop induction variable to the minimum valid index that seg6_action_params is initialized to. Reported-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Link: https://lore.kernel.org/r/20220802161203.622293-1-ndesaulniers@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
bc3410f250
commit
ac0dbed9ba
|
@ -1614,7 +1614,7 @@ static void __destroy_attrs(unsigned long parsed_attrs, int max_parsed,
|
||||||
* callback. If the callback is not available, then we skip to the next
|
* callback. If the callback is not available, then we skip to the next
|
||||||
* attribute; otherwise, we call the destroy() callback.
|
* attribute; otherwise, we call the destroy() callback.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < max_parsed; ++i) {
|
for (i = SEG6_LOCAL_SRH; i < max_parsed; ++i) {
|
||||||
if (!(parsed_attrs & SEG6_F_ATTR(i)))
|
if (!(parsed_attrs & SEG6_F_ATTR(i)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1643,7 +1643,7 @@ static int parse_nla_optional_attrs(struct nlattr **attrs,
|
||||||
struct seg6_action_param *param;
|
struct seg6_action_param *param;
|
||||||
int err, i;
|
int err, i;
|
||||||
|
|
||||||
for (i = 0; i < SEG6_LOCAL_MAX + 1; ++i) {
|
for (i = SEG6_LOCAL_SRH; i < SEG6_LOCAL_MAX + 1; ++i) {
|
||||||
if (!(desc->optattrs & SEG6_F_ATTR(i)) || !attrs[i])
|
if (!(desc->optattrs & SEG6_F_ATTR(i)) || !attrs[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1742,7 +1742,7 @@ static int parse_nla_action(struct nlattr **attrs, struct seg6_local_lwt *slwt)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse the required attributes */
|
/* parse the required attributes */
|
||||||
for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) {
|
for (i = SEG6_LOCAL_SRH; i < SEG6_LOCAL_MAX + 1; i++) {
|
||||||
if (desc->attrs & SEG6_F_ATTR(i)) {
|
if (desc->attrs & SEG6_F_ATTR(i)) {
|
||||||
if (!attrs[i])
|
if (!attrs[i])
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -1847,7 +1847,7 @@ static int seg6_local_fill_encap(struct sk_buff *skb,
|
||||||
|
|
||||||
attrs = slwt->desc->attrs | slwt->parsed_optattrs;
|
attrs = slwt->desc->attrs | slwt->parsed_optattrs;
|
||||||
|
|
||||||
for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) {
|
for (i = SEG6_LOCAL_SRH; i < SEG6_LOCAL_MAX + 1; i++) {
|
||||||
if (attrs & SEG6_F_ATTR(i)) {
|
if (attrs & SEG6_F_ATTR(i)) {
|
||||||
param = &seg6_action_params[i];
|
param = &seg6_action_params[i];
|
||||||
err = param->put(skb, slwt);
|
err = param->put(skb, slwt);
|
||||||
|
@ -1927,7 +1927,7 @@ static int seg6_local_cmp_encap(struct lwtunnel_state *a,
|
||||||
if (attrs_a != attrs_b)
|
if (attrs_a != attrs_b)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) {
|
for (i = SEG6_LOCAL_SRH; i < SEG6_LOCAL_MAX + 1; i++) {
|
||||||
if (attrs_a & SEG6_F_ATTR(i)) {
|
if (attrs_a & SEG6_F_ATTR(i)) {
|
||||||
param = &seg6_action_params[i];
|
param = &seg6_action_params[i];
|
||||||
if (param->cmp(slwt_a, slwt_b))
|
if (param->cmp(slwt_a, slwt_b))
|
||||||
|
|
Loading…
Reference in New Issue