CVE-2021-32458
A privilege escalation vulnerability exists in the tdts.ko chrdev_ioctl_handle functionality of Trend Micro, Inc. Home Network Security 6.1.567. A specially crafted ioctl can lead to code execution. An attacker can issue an ioctl to trigger this vulnerability.
Trend Micro, Inc. Home Network Security 6.1.567
https://www.trendmicro.com/en_us/forHome/products/homenetworksecurity.html
7.8 - CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CWE-121 - Stack-based Buffer Overflow
The Home Network Security Station is a device used to monitor and protect home networks from security threats as well as offer simple network management features. The Station provides vulnerability scanning, web threat protection, intrusion prevention, as well as device-based access control for all devices on a home network.
This vulnerability is caused by the lack of input validation on a user’s ioctl
request from user land. The upper 16 bits from the ioctl request (AND with 0x3FFF, so 14 bits total) are blindly used as input to __copy_from_user
to a stack-based buffer in kernel space. The stack-based buffer is smaller than the maximum ioctl request copy size of 0x3FFF and thus overflows. A user can carefully craft input such that they could get control over PC within due to this copy.
chrdev_ioctl_handle:
0000074c 10402de9 push {r4, lr} {__saved_lr} {__saved_r4}
00000750 5034e7e7 ubfx r3, r0, #0x8, #0x8
00000754 be0053e3 cmp r3, #0xbe
00000758 1800e013 mvnne r0, #0x18 {0xffffffe7}
0000075c 38d04de2 sub sp, sp, #0x38
00000760 2900001a bne 0x80c
// Check that the bits 8-15 are 0xbe in the IOCTL request
00000764 ff0010e3 tst r0, #0xff
00000768 1500e003 mvneq r0, #0x15 {0xffffffea}
0000076c 2600000a beq 0x80c
00000770 0d20a0e1 mov r2, sp {var_40}
00000774 000050e3 cmp r0, #0
00000778 7f3dc2e3 bic r3, r2, #0x1fc0 {var_40}
// Extract the size of the buffer encoded in the IOCTL request
0000077c 5028ede7 ubfx r2, r0, #0x10, #0xe
00000780 3f30c3e3 bic r3, r3, #0x3f
00000784 380000ba blt 0x86c
// Sanity checks to make sure that the encoded size is not negative
0000086c 084093e5 ldr r4, [r3, #0x8]
00000870 020091e0 add.s r0, r1, r2
00000874 0400d030 sbc.slo r0, r0, r4
00000878 0040a033 movlo r4, #0
0000087c 000054e3 cmp r4, #0
00000880 c3ffff0a beq 0x794
00000794 083093e5 ldr r3, [r3, #0x8]
00000798 020091e0 add.s r0, r1, r2
0000079c 0300d030 sbc.slo r0, r0, r3
000007a0 0030a033 movlo r3, #0
000007a4 000053e3 cmp r3, #0
000007a8 2a00000a beq 0x858
// Vulnerable __copy_from_user with user provided length and set size stack-buffer
00000858 0d00a0e1 mov r0, sp {var_40}
0000085c bb6901eb bl __copy_from_user
vmalloc: allocation failure: 1094795585 bytes
poc: page allocation failure: order:0, mode:0xd2
CPU: 0 PID: 1878 Comm: poc Tainted: P O 3.10.70 #2
[<80014774>] (unwindbacktrace+0x0/0xec) from [<80011a2c>] (showstack+0x10/0x14)
[<80011a2c>] (showstack+0x10/0x14) from [<80089ba0>] (warnallocfailed+0xe4/0x11c)
[<80089ba0>] (warnallocfailed+0xe4/0x11c) from [<800af704>] (vmallocnoderange+0x14c/0x220)
[<800af704>] (vmallocnoderange+0x14c/0x220) from [<800afa8c>] (vmalloc+0x58/0x60)
[<800afa8c>] (vmalloc+0x58/0x60) from [<7f000b68>] (tdtsshellioctlsig+0xa8/0xf54 [tdts])
[<7f000b68>] (tdtsshellioctlsig+0xa8/0xf54 [tdts]) from [<7f000854>] (chrdevrelease+0x110/0x164 [tdts])
[<7f000854>] (chrdevrelease+0x110/0x164 [tdts]) from [<41414141>] (0x41414141)
Mem-info:
Normal per-cpu:
CPU 0: hi: 90, btch: 15 usd: 63
activeanon:1483 inactiveanon:136 isolatedanon:0
activefile:2696 inactivefile:10865 isolatedfile:0
unevictable:0 dirty:14 writeback:0 unstable:0
free:35763 slabreclaimable:335 slabunreclaimable:1622
mapped:1445 shmem:145 pagetables:122 bounce:0
freecma:0
Normal free:143052kB min:2016kB low:2520kB high:3024kB activeanon:5932kB inactiveanon:544kB activefile:10784kB inactivefile:43460kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:262144kB managed:254312kB mlocked:0kB dirty:56kB writeback:0kB mapped:5780kB shmem:580kB slabreclaimable:1340kB slabunreclaimable:6488kB kernelstack:512kB pagetables:488kB unstable:0kB bounce:0kB freecma:0kB writebacktmp:0kB pagesscanned:0 allunreclaimable? no
lowmemreserve[]: 0 0
Normal: 454kB (UM) 278kB (UEM) 816kB (UM) 432kB (U) 164kB (M) 2128kB (EM) 1256kB (M) 3512kB (UEM) 11024kB (U) 22048kB (UE) 334096kB (UMR) = 143052kB
13706 total pagecache pages
0 pages in swap cache
Swap cache stats: add 0, delete 0, find 0/0
Free swap = 0kB
Total swap = 0kB
65536 pages of RAM
35996 free pages
1906 reserved pages
1785 slab pages
268512 pages shared
0 pages swap cached
ERROR: [tdtsshellioctlsigopgetbndwthdb:854] Cannot malloc container 1094795585 bytes
Unable to handle kernel paging request at virtual address 41414140
pgd = 8ada0000
[41414140] pgd=00000000
Internal error: Oops: 80000005 [#1] SMP ARM
Modules linked in: kmdiamond(O) tdtsudb(PO) tdts(PO)
CPU: 0 PID: 1878 Comm: poc Tainted: P O 3.10.70 #2
task: 8f99fa40 ti: 8f248000 task.ti: 8f248000
PC is at 0x41414140
LR is at 0x41414141
pc : [<41414140>] lr : [<41414141>] psr: 60000033
sp : 8f249f28 ip : 00000000 fp : 7efffc34
r10: 00000000 r9 : 8f248000 r8 : 8ada6300
r7 : 00000003 r6 : 8ada6300 r5 : 7effbc18 r4 : 41414141
r3 : 8052647c r2 : 8052647c r1 : 20000093 r0 : fffffff4
Flags: nZCv IRQs on FIQs on Mode SVC32 ISA Thumb Segment user
Control: 10c53c7d Table: 6ada006a DAC: 00000015
Process poc (pid: 1878, stack limit = 0x8f248238)
Stack: (0x8f249f28 to 0x8f24a000)
9f20: 41414141 41414141 41414141 41414141 41414141 41414141
9f40: 41414141 41414141 41414141 41414141 41414141 41414141 41414141 41414141
9f60: 41414141 41414141 41414141 41414141 41414141 41414141 41414141 41414141
9f80: 41414141 41414141 41414141 41414141 41414141 41414141 41414141 41414141
9fa0: 41414141 41414141 41414141 41414141 41414141 41414141 41414141 41414141
9fc0: 41414141 41414141 41414141 41414141 41414141 41414141 41414141 41414141
9fe0: 41414141 41414141 41414141 41414141 41414141 41414141 41414141 41414141
Code: bad PC value
---[ end trace 1e20ae6e53da58f1 ]---
Dec 2 20:24:17 Diamond user.warn kernel: vmalloc: allocation failure: 1094795585 bytes
Dec 2 20:24:17 Diamond user.warn kernel: poc: page allocation failure: order:0, mode:0xd2
Dec 2 20:24:17 Diamond user.warn kernel: CPU: 0 PID: 1878 Comm: poc Tainted: P O 3.10.70 #2
Dec 2 20:24:17 Diamond user.warn kernel: [<80014774>] (unwindbacktrace+0x0/0xec) from [<80011a2c>] (showstack+0x10/0x14)
Dec 2 20:24:17 Diamond user.warn kernel: [<80011a2c>] (showstack+0x10/0x14) from [<80089ba0>] (warnallocfailed+0xe4/0x11c)
Dec 2 20:24:17 Diamond user.warn kernel: [<80089ba0>] (warnallocfailed+0xe4/0x11c) from [<800af704>] (vmallocnoderange+0x14c/0x220)
Dec 2 20:24:17 Diamond user.warn kernel: [<800af704>] (vmallocnoderange+0x14c/0x220) from [<800afa8c>] (vmalloc+0x58/0x60)
Dec 2 20:24:17 Diamond user.warn kernel: [<800afa8c>] (vmalloc+0x58/0x60) from [<7f000b68>] (tdtsshellioctlsig+0xa8/0xf54 [tdts])
Dec 2 20:24:17 Diamond user.warn kernel: [<7f000b68>] (tdtsshellioctlsig+0xa8/0xf54 [tdts]) from [<7f000854>] (chrdevrelease+0x110/0x164 [tdts])
Dec 2 20:24:17 Diamond user.warn kernel: [<7f000854>] (chrdevrelease+0x110/0x164 [tdts]) from [<41414141>] (0x41414141)
Dec 2 20:24:17 Diamond user.warn kernel: Mem-info:
Dec 2 20:24:17 Diamond user.warn kernel: Normal per-cpu:
Dec 2 20:24:17 Diamond user.warn kernel: CPU 0: hi: 90, btch: 15 usd: 63
Dec 2 20:24:17 Diamond user.warn kernel: activeanon:1483 inactiveanon:136 isolatedanon:0
Dec 2 20:24:17 Diamond user.warn kernel: activefile:2696 inactivefile:10865 isolatedfile:0
Dec 2 20:24:17 Diamond user.warn kernel: unevictable:0 dirty:14 writeback:0 unstable:0
Dec 2 20:24:17 Diamond user.warn kernel: free:35763 slabreclaimable:335 slabunreclaimable:1622
Dec 2 20:24:17 Diamond user.warn kernel: mapped:1445 shmem:145 pagetables:122 bounce:0
Dec 2 20:24:17 Diamond user.warn kernel: freecma:0
Dec 2 20:24:17 Diamond user.warn kernel: Normal free:143052kB min:2016kB low:2520kB high:3024kB activeanon:5932kB inactiveanon:544kB activefile:10784kB inactivefile:43460kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:262144kB managed:254312kB mlo
Dec 2 20:24:17 Diamond user.warn kernel: lowmemreserve[]: 0 0
Dec 2 20:24:17 Diamond user.warn kernel: Normal: 454kB (UM) 278kB (UEM) 816kB (UM) 432kB (U) 164kB (M) 2128kB (EM) 1256kB (M) 3512kB (UEM) 11024kB (U) 22048kB (UE) 334096kB (UMR) = 143052kB
Dec 2 20:24:17 Diamond user.warn kernel: 13706 total pagecache pages
Dec 2 20:24:17 Diamond user.warn kernel: 0 pages in swap cache
Dec 2 20:24:17 Diamond user.warn kernel: Swap cache stats: add 0, delete 0, find 0/0
Dec 2 20:24:17 Diamond user.warn kernel: Free swap = 0kB
Dec 2 20:24:17 Diamond user.warn kernel: Total swap = 0kB
Dec 2 20:24:17 Diamond user.warn kernel: 65536 pages of RAM
Dec 2 20:24:17 Diamond user.warn kernel: 35996 free pages
Dec 2 20:24:17 Diamond user.warn kernel: 1906 reserved pages
Dec 2 20:24:17 Diamond user.warn kernel: 1785 slab pages
Dec 2 20:24:17 Diamond user.warn kernel: 268512 pages shared
Dec 2 20:24:17 Diamond user.warn kernel: 0 pages swap cached
Dec 2 20:24:17 Diamond user.err kernel: ERROR: [tdtsshellioctlsigopgetbndwthdb:854] Cannot malloc container 1094795585 bytes
Dec 2 20:24:17 Diamond user.alert kernel: Unable to handle kernel paging request at virtual address 41414140
Dec 2 20:24:17 Diamond user.alert kernel: pgd = 8ada0000
Dec 2 20:24:17 Diamond user.alert kernel: [41414140] pgd=00000000
Dec 2 20:24:17 Diamond user.emerg kernel: Internal error: Oops: 80000005 [#1] SMP ARM
Dec 2 20:24:17 Diamond user.warn kernel: Modules linked in: kmdiamond(O) tdtsudb(PO) tdts(PO)
Dec 2 20:24:17 Diamond user.warn kernel: CPU: 0 PID: 1878 Comm: poc Tainted: P O 3.10.70 #2
Dec 2 20:24:17 Diamond user.warn kernel: task: 8f99fa40 ti: 8f248000 task.ti: 8f248000
Dec 2 20:24:17 Diamond user.warn kernel: PC is at 0x41414140
Dec 2 20:24:17 Diamond user.warn kernel: LR is at 0x41414141
Dec 2 20:24:17 Diamond user.warn kernel: pc : [<41414140>] lr : [<41414141>] psr: 60000033
Dec 2 20:24:17 Diamond user.warn kernel: sp : 8f249f28 ip : 00000000 fp : 7efffc34
Dec 2 20:24:17 Diamond user.warn kernel: r10: 00000000 r9 : 8f248000 r8 : 8ada6300
Dec 2 20:24:17 Diamond user.warn kernel: r7 : 00000003 r6 : 8ada6300 r5 : 7effbc18 r4 : 41414141
Dec 2 20:24:17 Diamond user.warn kernel: r3 : 8052647c r2 : 8052647c r1 : 20000093 r0 : fffffff4
Dec 2 20:24:17 Diamond user.warn kernel: Flags: nZCv IRQs on FIQs on Mode SVC32 ISA Thumb Segment user
Dec 2 20:24:17 Diamond user.warn kernel: Control: 10c53c7d Table: 6ada006a DAC: 00000015
Dec 2 20:24:17 Diamond user.emerg kernel: Process poc (pid: 1878, stack limit = 0x8f248238)
Dec 2 20:24:17 Diamond user.emerg kernel: Stack: (0x8f249f28 to 0x8f24a000)
Dec 2 20:24:17 Diamond user.emerg kernel: 9f20: 41414141 41414141 41414141 41414141 41414141 41414141
Dec 2 20:24:17 Diamond user.emerg kernel: 9f40: 41414141 41414141 41414141 41414141 41414141 41414141 41414141 41414141
Dec 2 20:24:17 Diamond user.emerg kernel: 9f60: 41414141 41414141 41414141 41414141 41414141 41414141 41414141 41414141
Dec 2 20:24:17 Diamond user.emerg kernel: 9f80: 41414141 41414141 41414141 41414141 41414141 41414141 41414141 41414141
Dec 2 20:24:17 Diamond user.emerg kernel: 9fa0: 41414141 41414141 41414141 41414141 41414141 41414141 41414141 41414141
Dec 2 20:24:17 Diamond user.emerg kernel: 9fc0: 41414141 41414141 41414141 41414141 41414141 41414141 41414141 41414141
Dec 2 20:24:17 Diamond user.emerg kernel: 9fe0: 41414141 41414141 41414141 41414141 41414141 41414141 41414141 41414141
Dec 2 20:24:17 Diamond user.emerg kernel: Code: bad PC value
Dec 2 20:24:17 Diamond user.warn kernel: ---[ end trace 1e20ae6e53da58f1 ]---*
2021-01-22 - Vendor Disclosure
2021-04-06 - 75+ day follow up
2021-04-20 - Talos granted timeline extension for disclosure
2021-05-20 - Vendor Patched
2021-05-24 - Public Release
Discovered by Carl Hurd and Kelly Leuschner of Cisco Talos.