Message ID | 20220706034752.5729-1-hoang.h.le@dektech.com.au (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net] tipc: fix uninit-value in tipc_nl_node_reset_link_stats | expand |
On Wed, 6 Jul 2022 10:47:52 +0700 Hoang Le wrote: > diff --git a/net/tipc/node.c b/net/tipc/node.c > index b48d97cbbe29..80885780caa2 100644 > --- a/net/tipc/node.c > +++ b/net/tipc/node.c > @@ -2574,8 +2574,10 @@ int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info) > if (!attrs[TIPC_NLA_LINK_NAME]) > return -EINVAL; > > - link_name = nla_data(attrs[TIPC_NLA_LINK_NAME]); > + if (nla_len(attrs[TIPC_NLA_LINK_NAME]) <= 0) > + return -EINVAL; > > + link_name = nla_data(attrs[TIPC_NLA_LINK_NAME]); > err = -EINVAL; > if (!strcmp(link_name, tipc_bclink_name)) { > err = tipc_bclink_reset_stats(net, tipc_bc_sndlink(net)); I think you misunderstood me. Let me try to explain in more detail. AFAICT the attrs in this function get validated using the tipc_nl_link_policy: https://elixir.bootlin.com/linux/v5.19-rc4/source/net/tipc/node.c#L2567 This policy specifies the type for TIPC_NLA_LINK_NAME as NLA_STRING: https://elixir.bootlin.com/linux/v5.19-rc4/source/net/tipc/netlink.c#L91 Therefore we can assume that the attribute is a valid (but not necessarily null-terminated) string. Otherwise nla_parse_nested_deprecated() would have returned an error. The code for NLA_STRING validation is here: https://elixir.bootlin.com/linux/v5.19-rc4/source/lib/nlattr.c#L437 So we can already assume that the attribute is not empty. The bug you're fixing is that the string is not null-terminated, so strcmp() can read past the end of the attribute. What I was trying to suggest is that you change the policy from NLA_STRING to NLA_NUL_STRING, which also checks that the string is NULL-terminated. Please note that it'd be a slight uAPI change, and could break applications which expect kernel to not require null-termination. Perhaps tipc developers can guide us on how likely that is. Alternative is to use strncmp(..., nla_len(attr)).
On Wed, 6 Jul 2022 13:33:34 -0700 Jakub Kicinski wrote:
> Alternative is to use strncmp(..., nla_len(attr)).
Correction, we have helpers for this - nla_strcmp etc.
> -----Original Message----- > From: Jakub Kicinski <kuba@kernel.org> > Sent: Thursday, July 7, 2022 3:34 AM > To: Hoang Huu Le <hoang.h.le@dektech.com.au> > Cc: jmaloy@redhat.com; maloy@donjonn.com; ying.xue@windriver.com; Tung Quang Nguyen <tung.q.nguyen@dektech.com.au>; > pabeni@redhat.com; edumazet@google.com; tipc-discussion@lists.sourceforge.net; netdev@vger.kernel.org; > davem@davemloft.net; syzbot+a73d24a22eeeebe5f244@syzkaller.appspotmail.com > Subject: Re: [net] tipc: fix uninit-value in tipc_nl_node_reset_link_stats > > On Wed, 6 Jul 2022 10:47:52 +0700 Hoang Le wrote: > > diff --git a/net/tipc/node.c b/net/tipc/node.c > > index b48d97cbbe29..80885780caa2 100644 > > --- a/net/tipc/node.c > > +++ b/net/tipc/node.c > > @@ -2574,8 +2574,10 @@ int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info) > > if (!attrs[TIPC_NLA_LINK_NAME]) > > return -EINVAL; > > > > - link_name = nla_data(attrs[TIPC_NLA_LINK_NAME]); > > + if (nla_len(attrs[TIPC_NLA_LINK_NAME]) <= 0) > > + return -EINVAL; > > > > + link_name = nla_data(attrs[TIPC_NLA_LINK_NAME]); > > err = -EINVAL; > > if (!strcmp(link_name, tipc_bclink_name)) { > > err = tipc_bclink_reset_stats(net, tipc_bc_sndlink(net)); > > I think you misunderstood me. Let me try to explain in more detail. > > AFAICT the attrs in this function get validated using the > tipc_nl_link_policy: > > https://elixir.bootlin.com/linux/v5.19-rc4/source/net/tipc/node.c#L2567 > > This policy specifies the type for TIPC_NLA_LINK_NAME as NLA_STRING: > > https://elixir.bootlin.com/linux/v5.19-rc4/source/net/tipc/netlink.c#L91 > > Therefore we can assume that the attribute is a valid (but not > necessarily null-terminated) string. Otherwise > nla_parse_nested_deprecated() would have returned an error. > > The code for NLA_STRING validation is here: > > https://elixir.bootlin.com/linux/v5.19-rc4/source/lib/nlattr.c#L437 > > So we can already assume that the attribute is not empty. > > The bug you're fixing is that the string is not null-terminated, > so strcmp() can read past the end of the attribute. > No, I'm trying to fix below issues: BUG: KMSAN: uninit-value in strlen lib/string.c:495 [inline] BUG: KMSAN: uninit-value in strstr+0xb4/0x2e0 lib/string.c:840 strlen lib/string.c:495 [inline] strstr+0xb4/0x2e0 lib/string.c:840 tipc_nl_node_reset_link_stats+0x41e/0xba0 net/tipc/node.c:2582 I assume the link name attribute is empty as root cause. So, just checking length is enough for fixing this issue. > What I was trying to suggest is that you change the policy from > NLA_STRING to NLA_NUL_STRING, which also checks that the string > is NULL-terminated. > > Please note that it'd be a slight uAPI change, and could break > applications which expect kernel to not require null-termination. > Perhaps tipc developers can guide us on how likely that is. > Alternative is to use strncmp(..., nla_len(attr)).
On Thu, 7 Jul 2022 00:22:06 +0000 Hoang Huu Le wrote: > > The bug you're fixing is that the string is not null-terminated, > > so strcmp() can read past the end of the attribute. > > > No, I'm trying to fix below issues: > > BUG: KMSAN: uninit-value in strlen lib/string.c:495 [inline] > BUG: KMSAN: uninit-value in strstr+0xb4/0x2e0 lib/string.c:840 > strlen lib/string.c:495 [inline] > strstr+0xb4/0x2e0 lib/string.c:840 > tipc_nl_node_reset_link_stats+0x41e/0xba0 net/tipc/node.c:2582 > > I assume the link name attribute is empty as root cause. > So, just checking length is enough for fixing this issue. I pointed you to the code that does NLA_STRING validation and that already checks: if (attrlen < 1) what am I missing?
> -----Original Message----- > From: Jakub Kicinski <kuba@kernel.org> > Sent: Thursday, July 7, 2022 7:58 AM > To: Hoang Huu Le <hoang.h.le@dektech.com.au> > Cc: jmaloy@redhat.com; maloy@donjonn.com; ying.xue@windriver.com; Tung Quang Nguyen <tung.q.nguyen@dektech.com.au>; > pabeni@redhat.com; edumazet@google.com; tipc-discussion@lists.sourceforge.net; netdev@vger.kernel.org; > davem@davemloft.net; syzbot+a73d24a22eeeebe5f244@syzkaller.appspotmail.com > Subject: Re: [net] tipc: fix uninit-value in tipc_nl_node_reset_link_stats > > On Thu, 7 Jul 2022 00:22:06 +0000 Hoang Huu Le wrote: > > > The bug you're fixing is that the string is not null-terminated, > > > so strcmp() can read past the end of the attribute. > > > > > No, I'm trying to fix below issues: > > > > BUG: KMSAN: uninit-value in strlen lib/string.c:495 [inline] > > BUG: KMSAN: uninit-value in strstr+0xb4/0x2e0 lib/string.c:840 > > strlen lib/string.c:495 [inline] > > strstr+0xb4/0x2e0 lib/string.c:840 > > tipc_nl_node_reset_link_stats+0x41e/0xba0 net/tipc/node.c:2582 > > > > I assume the link name attribute is empty as root cause. > > So, just checking length is enough for fixing this issue. > > I pointed you to the code that does NLA_STRING validation and that > already checks: > > if (attrlen < 1) > > what am I missing? You're correct! I will post v3 when I find out a better solution to solve the problem.
diff --git a/net/tipc/node.c b/net/tipc/node.c index b48d97cbbe29..80885780caa2 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -2574,8 +2574,10 @@ int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info) if (!attrs[TIPC_NLA_LINK_NAME]) return -EINVAL; - link_name = nla_data(attrs[TIPC_NLA_LINK_NAME]); + if (nla_len(attrs[TIPC_NLA_LINK_NAME]) <= 0) + return -EINVAL; + link_name = nla_data(attrs[TIPC_NLA_LINK_NAME]); err = -EINVAL; if (!strcmp(link_name, tipc_bclink_name)) { err = tipc_bclink_reset_stats(net, tipc_bc_sndlink(net));