Talos Vulnerability Report

TALOS-2021-1231

Trend Micro Inc. Home Network Security tdts.ko chrdev_ioctl_handle privilege escalation vulnerability

May 24, 2021
CVE Number

CVE-2021-32458

Summary

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.

Tested Versions

Trend Micro, Inc. Home Network Security 6.1.567

Product URLs

https://www.trendmicro.com/en_us/forHome/products/homenetworksecurity.html

CVSSv3 Score

7.8 - CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

CWE

CWE-121 - Stack-based Buffer Overflow

Details

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

Crash Information

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 ]---*

Timeline

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

Credit

Discovered by Carl Hurd and Kelly Leuschner of Cisco Talos.