diff options
author | Cong Wang <xiyou.wangcong@gmail.com> | 2018-09-06 14:50:16 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-09-07 23:05:07 -0700 |
commit | a162c3511410b50f09c002fea56fea2153b679d0 (patch) | |
tree | a687a142f1edc5d5246cb6b46453ae53ddbd4dc2 /net | |
parent | 8edfe2e992b75aee3da9316e9697c531194c2f53 (diff) | |
download | linux-stable-a162c3511410b50f09c002fea56fea2153b679d0.tar.gz linux-stable-a162c3511410b50f09c002fea56fea2153b679d0.tar.bz2 linux-stable-a162c3511410b50f09c002fea56fea2153b679d0.zip |
net_sched: properly cancel netlink dump on failure
When nla_put*() fails after nla_nest_start(), we need
to call nla_nest_cancel() to cancel the message, otherwise
we end up calling nla_nest_end() like a success.
Fixes: 0ed5269f9e41 ("net/sched: add tunnel option support to act_tunnel_key")
Cc: Davide Caratti <dcaratti@redhat.com>
Cc: Simon Horman <simon.horman@netronome.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/sched/act_tunnel_key.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c index 28d58bbc953e..681f6f04e7da 100644 --- a/net/sched/act_tunnel_key.c +++ b/net/sched/act_tunnel_key.c @@ -412,8 +412,10 @@ static int tunnel_key_geneve_opts_dump(struct sk_buff *skb, nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE, opt->type) || nla_put(skb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA, - opt->length * 4, opt + 1)) + opt->length * 4, opt + 1)) { + nla_nest_cancel(skb, start); return -EMSGSIZE; + } len -= sizeof(struct geneve_opt) + opt->length * 4; src += sizeof(struct geneve_opt) + opt->length * 4; @@ -427,7 +429,7 @@ static int tunnel_key_opts_dump(struct sk_buff *skb, const struct ip_tunnel_info *info) { struct nlattr *start; - int err; + int err = -EINVAL; if (!info->options_len) return 0; @@ -439,9 +441,11 @@ static int tunnel_key_opts_dump(struct sk_buff *skb, if (info->key.tun_flags & TUNNEL_GENEVE_OPT) { err = tunnel_key_geneve_opts_dump(skb, info); if (err) - return err; + goto err_out; } else { - return -EINVAL; +err_out: + nla_nest_cancel(skb, start); + return err; } nla_nest_end(skb, start); |