diff mbox series

tipc: Fix uninit-value access in __tipc_nl_bearer_enable()

Message ID 20230926125120.152133-1-syoshida@redhat.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series tipc: Fix uninit-value access in __tipc_nl_bearer_enable() | expand

Checks

Context Check Description
netdev/series_format warning Single patches do not need cover letters; Target tree name not specified in the subject
netdev/tree_selection success Guessed tree name to be net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1340 this patch: 1340
netdev/cc_maintainers fail 3 blamed authors not CCed: richard.alpe@ericsson.com erik.hugne@ericsson.com davem@davemloft.net; 6 maintainers not CCed: pabeni@redhat.com davem@davemloft.net edumazet@google.com richard.alpe@ericsson.com erik.hugne@ericsson.com kuba@kernel.org
netdev/build_clang success Errors and warnings before: 1363 this patch: 1363
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 1363 this patch: 1363
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 10 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Shigeru Yoshida Sept. 26, 2023, 12:51 p.m. UTC
syzbot reported the following uninit-value access issue:

=====================================================
BUG: KMSAN: uninit-value in strscpy+0xc4/0x160
 strscpy+0xc4/0x160
 bearer_name_validate net/tipc/bearer.c:147 [inline]
 tipc_enable_bearer net/tipc/bearer.c:259 [inline]
 __tipc_nl_bearer_enable+0x634/0x2220 net/tipc/bearer.c:1043
 tipc_nl_bearer_enable+0x3c/0x70 net/tipc/bearer.c:1052
 genl_family_rcv_msg_doit net/netlink/genetlink.c:971 [inline]
 genl_family_rcv_msg net/netlink/genetlink.c:1051 [inline]
 genl_rcv_msg+0x11ec/0x1290 net/netlink/genetlink.c:1066
 netlink_rcv_skb+0x371/0x650 net/netlink/af_netlink.c:2545
 genl_rcv+0x40/0x60 net/netlink/genetlink.c:1075
 netlink_unicast_kernel net/netlink/af_netlink.c:1342 [inline]
 netlink_unicast+0xf47/0x1250 net/netlink/af_netlink.c:1368
 netlink_sendmsg+0x1238/0x13d0 net/netlink/af_netlink.c:1910
 sock_sendmsg_nosec net/socket.c:730 [inline]
 sock_sendmsg net/socket.c:753 [inline]
 ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2540
 ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2594
 __sys_sendmsg net/socket.c:2623 [inline]
 __do_sys_sendmsg net/socket.c:2632 [inline]
 __se_sys_sendmsg net/socket.c:2630 [inline]
 __x64_sys_sendmsg+0x307/0x490 net/socket.c:2630
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd

Uninit was created at:
 slab_post_alloc_hook+0x12f/0xb70 mm/slab.h:767
 slab_alloc_node mm/slub.c:3478 [inline]
 kmem_cache_alloc_node+0x577/0xa80 mm/slub.c:3523
 kmalloc_reserve+0x148/0x470 net/core/skbuff.c:559
 __alloc_skb+0x318/0x740 net/core/skbuff.c:644
 alloc_skb include/linux/skbuff.h:1286 [inline]
 netlink_alloc_large_skb net/netlink/af_netlink.c:1214 [inline]
 netlink_sendmsg+0xb34/0x13d0 net/netlink/af_netlink.c:1885
 sock_sendmsg_nosec net/socket.c:730 [inline]
 sock_sendmsg net/socket.c:753 [inline]
 ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2540
 ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2594
 __sys_sendmsg net/socket.c:2623 [inline]
 __do_sys_sendmsg net/socket.c:2632 [inline]
 __se_sys_sendmsg net/socket.c:2630 [inline]
 __x64_sys_sendmsg+0x307/0x490 net/socket.c:2630
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd

Bearer names must be null-terminated strings. If a bearer name which is not
null-terminated is passed through netlink, strcpy() and similar functions
can cause buffer overrun. This causes the above issue.

This patch fixes this issue by returning -EINVAL if a non-null-terminated
bearer name is passed.

Fixes: 0655f6a8635b ("tipc: add bearer disable/enable to new netlink api")
Reported-and-tested-by: syzbot+9425c47dccbcb4c17d51@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=9425c47dccbcb4c17d51
Signed-off-by: Shigeru Yoshida <syoshida@redhat.com>
---
 net/tipc/bearer.c | 4 ++++
 1 file changed, 4 insertions(+)

Comments

Simon Horman Oct. 1, 2023, 5:47 p.m. UTC | #1
On Tue, Sep 26, 2023 at 09:51:20PM +0900, Shigeru Yoshida wrote:
> syzbot reported the following uninit-value access issue:
> 
> =====================================================
> BUG: KMSAN: uninit-value in strscpy+0xc4/0x160
>  strscpy+0xc4/0x160
>  bearer_name_validate net/tipc/bearer.c:147 [inline]
>  tipc_enable_bearer net/tipc/bearer.c:259 [inline]
>  __tipc_nl_bearer_enable+0x634/0x2220 net/tipc/bearer.c:1043
>  tipc_nl_bearer_enable+0x3c/0x70 net/tipc/bearer.c:1052
>  genl_family_rcv_msg_doit net/netlink/genetlink.c:971 [inline]
>  genl_family_rcv_msg net/netlink/genetlink.c:1051 [inline]
>  genl_rcv_msg+0x11ec/0x1290 net/netlink/genetlink.c:1066
>  netlink_rcv_skb+0x371/0x650 net/netlink/af_netlink.c:2545
>  genl_rcv+0x40/0x60 net/netlink/genetlink.c:1075
>  netlink_unicast_kernel net/netlink/af_netlink.c:1342 [inline]
>  netlink_unicast+0xf47/0x1250 net/netlink/af_netlink.c:1368
>  netlink_sendmsg+0x1238/0x13d0 net/netlink/af_netlink.c:1910
>  sock_sendmsg_nosec net/socket.c:730 [inline]
>  sock_sendmsg net/socket.c:753 [inline]
>  ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2540
>  ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2594
>  __sys_sendmsg net/socket.c:2623 [inline]
>  __do_sys_sendmsg net/socket.c:2632 [inline]
>  __se_sys_sendmsg net/socket.c:2630 [inline]
>  __x64_sys_sendmsg+0x307/0x490 net/socket.c:2630
>  do_syscall_x64 arch/x86/entry/common.c:50 [inline]
>  do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
>  entry_SYSCALL_64_after_hwframe+0x63/0xcd
> 
> Uninit was created at:
>  slab_post_alloc_hook+0x12f/0xb70 mm/slab.h:767
>  slab_alloc_node mm/slub.c:3478 [inline]
>  kmem_cache_alloc_node+0x577/0xa80 mm/slub.c:3523
>  kmalloc_reserve+0x148/0x470 net/core/skbuff.c:559
>  __alloc_skb+0x318/0x740 net/core/skbuff.c:644
>  alloc_skb include/linux/skbuff.h:1286 [inline]
>  netlink_alloc_large_skb net/netlink/af_netlink.c:1214 [inline]
>  netlink_sendmsg+0xb34/0x13d0 net/netlink/af_netlink.c:1885
>  sock_sendmsg_nosec net/socket.c:730 [inline]
>  sock_sendmsg net/socket.c:753 [inline]
>  ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2540
>  ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2594
>  __sys_sendmsg net/socket.c:2623 [inline]
>  __do_sys_sendmsg net/socket.c:2632 [inline]
>  __se_sys_sendmsg net/socket.c:2630 [inline]
>  __x64_sys_sendmsg+0x307/0x490 net/socket.c:2630
>  do_syscall_x64 arch/x86/entry/common.c:50 [inline]
>  do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
>  entry_SYSCALL_64_after_hwframe+0x63/0xcd
> 
> Bearer names must be null-terminated strings. If a bearer name which is not
> null-terminated is passed through netlink, strcpy() and similar functions
> can cause buffer overrun. This causes the above issue.
> 
> This patch fixes this issue by returning -EINVAL if a non-null-terminated
> bearer name is passed.
> 
> Fixes: 0655f6a8635b ("tipc: add bearer disable/enable to new netlink api")
> Reported-and-tested-by: syzbot+9425c47dccbcb4c17d51@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=9425c47dccbcb4c17d51
> Signed-off-by: Shigeru Yoshida <syoshida@redhat.com>

Reviewed-by: Simon Horman <horms@kernel.org>
Paolo Abeni Oct. 3, 2023, 8:52 a.m. UTC | #2
On Tue, 2023-09-26 at 21:51 +0900, Shigeru Yoshida wrote:
> syzbot reported the following uninit-value access issue:
> 
> =====================================================
> BUG: KMSAN: uninit-value in strscpy+0xc4/0x160
>  strscpy+0xc4/0x160
>  bearer_name_validate net/tipc/bearer.c:147 [inline]
>  tipc_enable_bearer net/tipc/bearer.c:259 [inline]
>  __tipc_nl_bearer_enable+0x634/0x2220 net/tipc/bearer.c:1043
>  tipc_nl_bearer_enable+0x3c/0x70 net/tipc/bearer.c:1052
>  genl_family_rcv_msg_doit net/netlink/genetlink.c:971 [inline]
>  genl_family_rcv_msg net/netlink/genetlink.c:1051 [inline]
>  genl_rcv_msg+0x11ec/0x1290 net/netlink/genetlink.c:1066
>  netlink_rcv_skb+0x371/0x650 net/netlink/af_netlink.c:2545
>  genl_rcv+0x40/0x60 net/netlink/genetlink.c:1075
>  netlink_unicast_kernel net/netlink/af_netlink.c:1342 [inline]
>  netlink_unicast+0xf47/0x1250 net/netlink/af_netlink.c:1368
>  netlink_sendmsg+0x1238/0x13d0 net/netlink/af_netlink.c:1910
>  sock_sendmsg_nosec net/socket.c:730 [inline]
>  sock_sendmsg net/socket.c:753 [inline]
>  ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2540
>  ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2594
>  __sys_sendmsg net/socket.c:2623 [inline]
>  __do_sys_sendmsg net/socket.c:2632 [inline]
>  __se_sys_sendmsg net/socket.c:2630 [inline]
>  __x64_sys_sendmsg+0x307/0x490 net/socket.c:2630
>  do_syscall_x64 arch/x86/entry/common.c:50 [inline]
>  do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
>  entry_SYSCALL_64_after_hwframe+0x63/0xcd
> 
> Uninit was created at:
>  slab_post_alloc_hook+0x12f/0xb70 mm/slab.h:767
>  slab_alloc_node mm/slub.c:3478 [inline]
>  kmem_cache_alloc_node+0x577/0xa80 mm/slub.c:3523
>  kmalloc_reserve+0x148/0x470 net/core/skbuff.c:559
>  __alloc_skb+0x318/0x740 net/core/skbuff.c:644
>  alloc_skb include/linux/skbuff.h:1286 [inline]
>  netlink_alloc_large_skb net/netlink/af_netlink.c:1214 [inline]
>  netlink_sendmsg+0xb34/0x13d0 net/netlink/af_netlink.c:1885
>  sock_sendmsg_nosec net/socket.c:730 [inline]
>  sock_sendmsg net/socket.c:753 [inline]
>  ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2540
>  ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2594
>  __sys_sendmsg net/socket.c:2623 [inline]
>  __do_sys_sendmsg net/socket.c:2632 [inline]
>  __se_sys_sendmsg net/socket.c:2630 [inline]
>  __x64_sys_sendmsg+0x307/0x490 net/socket.c:2630
>  do_syscall_x64 arch/x86/entry/common.c:50 [inline]
>  do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
>  entry_SYSCALL_64_after_hwframe+0x63/0xcd
> 
> Bearer names must be null-terminated strings. If a bearer name which is not
> null-terminated is passed through netlink, strcpy() and similar functions
> can cause buffer overrun. This causes the above issue.
> 
> This patch fixes this issue by returning -EINVAL if a non-null-terminated
> bearer name is passed.
> 
> Fixes: 0655f6a8635b ("tipc: add bearer disable/enable to new netlink api")
> Reported-and-tested-by: syzbot+9425c47dccbcb4c17d51@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=9425c47dccbcb4c17d51
> Signed-off-by: Shigeru Yoshida <syoshida@redhat.com>
> ---
>  net/tipc/bearer.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
> index 2cde375477e3..62047d20e14d 100644
> --- a/net/tipc/bearer.c
> +++ b/net/tipc/bearer.c
> @@ -1025,6 +1025,10 @@ int __tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
>  
>  	bearer = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
>  
> +	if (bearer[strnlen(bearer,
> +			   nla_len(attrs[TIPC_NLA_BEARER_NAME]))] != '\0')

if 'bearer' is not NULL terminated, the above will access the first
byte after the TIPC_NLA_BEARER_NAME attribute.

I think it would cleaner and safer using nla_strscpy() instead.

Quickly skimming over the tpic code, most TIPC_NLA_BEARER_NAME access
looks unsafe, and possibly a similar fix should be applied in more
places.

Thanks,

Paolo
Shigeru Yoshida Oct. 4, 2023, 4:36 p.m. UTC | #3
On Tue, 03 Oct 2023 10:52:50 +0200, Paolo Abeni wrote:
> On Tue, 2023-09-26 at 21:51 +0900, Shigeru Yoshida wrote:
>> syzbot reported the following uninit-value access issue:
>> 
>> =====================================================
>> BUG: KMSAN: uninit-value in strscpy+0xc4/0x160
>>  strscpy+0xc4/0x160
>>  bearer_name_validate net/tipc/bearer.c:147 [inline]
>>  tipc_enable_bearer net/tipc/bearer.c:259 [inline]
>>  __tipc_nl_bearer_enable+0x634/0x2220 net/tipc/bearer.c:1043
>>  tipc_nl_bearer_enable+0x3c/0x70 net/tipc/bearer.c:1052
>>  genl_family_rcv_msg_doit net/netlink/genetlink.c:971 [inline]
>>  genl_family_rcv_msg net/netlink/genetlink.c:1051 [inline]
>>  genl_rcv_msg+0x11ec/0x1290 net/netlink/genetlink.c:1066
>>  netlink_rcv_skb+0x371/0x650 net/netlink/af_netlink.c:2545
>>  genl_rcv+0x40/0x60 net/netlink/genetlink.c:1075
>>  netlink_unicast_kernel net/netlink/af_netlink.c:1342 [inline]
>>  netlink_unicast+0xf47/0x1250 net/netlink/af_netlink.c:1368
>>  netlink_sendmsg+0x1238/0x13d0 net/netlink/af_netlink.c:1910
>>  sock_sendmsg_nosec net/socket.c:730 [inline]
>>  sock_sendmsg net/socket.c:753 [inline]
>>  ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2540
>>  ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2594
>>  __sys_sendmsg net/socket.c:2623 [inline]
>>  __do_sys_sendmsg net/socket.c:2632 [inline]
>>  __se_sys_sendmsg net/socket.c:2630 [inline]
>>  __x64_sys_sendmsg+0x307/0x490 net/socket.c:2630
>>  do_syscall_x64 arch/x86/entry/common.c:50 [inline]
>>  do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
>>  entry_SYSCALL_64_after_hwframe+0x63/0xcd
>> 
>> Uninit was created at:
>>  slab_post_alloc_hook+0x12f/0xb70 mm/slab.h:767
>>  slab_alloc_node mm/slub.c:3478 [inline]
>>  kmem_cache_alloc_node+0x577/0xa80 mm/slub.c:3523
>>  kmalloc_reserve+0x148/0x470 net/core/skbuff.c:559
>>  __alloc_skb+0x318/0x740 net/core/skbuff.c:644
>>  alloc_skb include/linux/skbuff.h:1286 [inline]
>>  netlink_alloc_large_skb net/netlink/af_netlink.c:1214 [inline]
>>  netlink_sendmsg+0xb34/0x13d0 net/netlink/af_netlink.c:1885
>>  sock_sendmsg_nosec net/socket.c:730 [inline]
>>  sock_sendmsg net/socket.c:753 [inline]
>>  ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2540
>>  ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2594
>>  __sys_sendmsg net/socket.c:2623 [inline]
>>  __do_sys_sendmsg net/socket.c:2632 [inline]
>>  __se_sys_sendmsg net/socket.c:2630 [inline]
>>  __x64_sys_sendmsg+0x307/0x490 net/socket.c:2630
>>  do_syscall_x64 arch/x86/entry/common.c:50 [inline]
>>  do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
>>  entry_SYSCALL_64_after_hwframe+0x63/0xcd
>> 
>> Bearer names must be null-terminated strings. If a bearer name which is not
>> null-terminated is passed through netlink, strcpy() and similar functions
>> can cause buffer overrun. This causes the above issue.
>> 
>> This patch fixes this issue by returning -EINVAL if a non-null-terminated
>> bearer name is passed.
>> 
>> Fixes: 0655f6a8635b ("tipc: add bearer disable/enable to new netlink api")
>> Reported-and-tested-by: syzbot+9425c47dccbcb4c17d51@syzkaller.appspotmail.com
>> Closes: https://syzkaller.appspot.com/bug?extid=9425c47dccbcb4c17d51
>> Signed-off-by: Shigeru Yoshida <syoshida@redhat.com>
>> ---
>>  net/tipc/bearer.c | 4 ++++
>>  1 file changed, 4 insertions(+)
>> 
>> diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
>> index 2cde375477e3..62047d20e14d 100644
>> --- a/net/tipc/bearer.c
>> +++ b/net/tipc/bearer.c
>> @@ -1025,6 +1025,10 @@ int __tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
>>  
>>  	bearer = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
>>  
>> +	if (bearer[strnlen(bearer,
>> +			   nla_len(attrs[TIPC_NLA_BEARER_NAME]))] != '\0')
> 
> if 'bearer' is not NULL terminated, the above will access the first
> byte after the TIPC_NLA_BEARER_NAME attribute.
> 
> I think it would cleaner and safer using nla_strscpy() instead.

Thank you so much for your comment.  I didn't notice the existence of
nla_strscpy().

> Quickly skimming over the tpic code, most TIPC_NLA_BEARER_NAME access
> looks unsafe, and possibly a similar fix should be applied in more
> places.

I've checked the usage of TIPC_NLA_BEARER_NAME accesses.  These might
cause the same issue, so the same fix should be needed, as you say.

I'll send a v2 patch.

Thanks,
Shigeru

> 
> Thanks,
> 
> Paolo
>
diff mbox series

Patch

diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 2cde375477e3..62047d20e14d 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -1025,6 +1025,10 @@  int __tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
 
 	bearer = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
 
+	if (bearer[strnlen(bearer,
+			   nla_len(attrs[TIPC_NLA_BEARER_NAME]))] != '\0')
+		return -EINVAL;
+
 	if (attrs[TIPC_NLA_BEARER_DOMAIN])
 		domain = nla_get_u32(attrs[TIPC_NLA_BEARER_DOMAIN]);