Activity log for bug #1883840

Date Who What changed Old value New value Message
2020-06-17 06:56:41 Hadar Manor bug added bug
2020-06-17 06:56:41 Hadar Manor attachment added material.7z https://bugs.launchpad.net/bugs/1883840/+attachment/5384643/+files/material.7z
2020-06-17 06:56:50 Hadar Manor linux (Ubuntu): assignee Hadar Manor (hadarm)
2020-06-17 06:57:30 Hadar Manor summary Double free in DCCP module causing kernel panic Double free in DCCP module causing kernel panic
2020-06-22 19:15:38 Mike Salvatore bug added subscriber Thadeu Lima de Souza Cascardo
2020-07-01 00:33:38 Seth Arnold bug added subscriber Terry Rudd
2020-07-01 00:33:46 Seth Arnold bug added subscriber Brad Figg
2020-08-18 18:21:26 Thadeu Lima de Souza Cascardo linux (Ubuntu): assignee Hadar Manor (hadarm) Thadeu Lima de Souza Cascardo (cascardo)
2020-08-31 16:20:29 Hadar Manor linux (Ubuntu): assignee Thadeu Lima de Souza Cascardo (cascardo) Hadar Manor (hadarm)
2020-08-31 16:26:14 Hadar Manor description I found this exploitable bug in Linux Kernel which affects all ubuntu distributions, I have responsibly disclosed and patched a pretty similar bug in late 2017, you can see the work here : https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-3.2.y&id=e23d13a89d8ca5fe717d75248672e1b8bc4a3be8. But the bug appears again in a different look and still affect the kernel. The problem is when the sock object gets cloned via dccp_create_openreq_child(), it gives all its attributes to the child sock object, and no reference counter is taken for the object dccps_hc_tx_ccid. If one of the sock objects (the parent or the cahild) is closes or disconnected, it frees the target objects dccps_hc_tx_ccid and provides us a dagling pointer in the other sock object. This causes an exploitable double free for an object contains function pointers. We can free dccps_hc_tx_ccid by calling connect(AF_UNSPEC),then spray the heap with other allocations, then call close() we'll potentially have a RIP control. This chunk of code is the responsible of freeing dccps_hc_tx_ccid, if called again it will call ccid_hc_tx_exit() from a freed object void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk) { if (ccid != NULL) { if (ccid->ccid_ops->ccid_hc_tx_exit != NULL) ccid->ccid_ops->ccid_hc_tx_exit(sk); // <-- Calling a function pointer kmem_cache_free(ccid->ccid_ops->ccid_hc_tx_slab, ccid); } } disassembly : (gdb) disas ccid_hc_tx_delete Dump of assembler code for function ccid_hc_tx_delete: 0xffffffff81a7a3a0 <+0>: test rdi,rdi 0xffffffff81a7a3a3 <+3>: je 0xffffffff81a7a3cd <ccid_hc_tx_delete+45> 0xffffffff81a7a3a5 <+5>: push rbx 0xffffffff81a7a3a6 <+6>: mov rbx,rdi 0xffffffff81a7a3a9 <+9>: mov rdi,rsi 0xffffffff81a7a3ac <+12>: mov rax,QWORD PTR [rbx] 0xffffffff81a7a3af <+15>: mov rdx,QWORD PTR [rax+0x80] <— rax points to a freed object 0xffffffff81a7a3b6 <+22>: test rdx,rdx 0xffffffff81a7a3b9 <+25>: je 0xffffffff81a7a3c0 <ccid_hc_tx_delete+32> 0xffffffff81a7a3bb <+27>: call rdx // <-- arbitrary call 0xffffffff81a7a3bd <+29>: mov rax,QWORD PTR [rbx] 0xffffffff81a7a3c0 <+32>: mov rsi,rbx 0xffffffff81a7a3c3 <+35>: mov rdi,QWORD PTR [rax+0x18] 0xffffffff81a7a3c7 <+39>: pop rbx 0xffffffff81a7a3c8 <+40>: jmp 0xffffffff811fb980 <kmem_cache_free> 0xffffffff81a7a3cd <+45>: repz ret End of assembler dump. The problem is when the sock object gets cloned via dccp_create_openreq_child(), it gives all its attributes to the child sock object, and no reference counter is taken for the object dccps_hc_tx_ccid. If one of the sock objects (the parent or the cahild) is closes or disconnected, it frees the target objects dccps_hc_tx_ccid and provides us a dagling pointer in the other sock object. This causes an exploitable double free for an object contains function pointers. We can free dccps_hc_tx_ccid by calling connect(AF_UNSPEC),then spray the heap with other allocations, then call close() we'll potentially have a RIP control. This chunk of code is the responsible of freeing dccps_hc_tx_ccid, if called again it will call ccid_hc_tx_exit() from a freed object void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk) {  if (ccid != NULL) {   if (ccid->ccid_ops->ccid_hc_tx_exit != NULL)    ccid->ccid_ops->ccid_hc_tx_exit(sk); // <-- Calling a function pointer   kmem_cache_free(ccid->ccid_ops->ccid_hc_tx_slab, ccid);  } } disassembly : (gdb) disas ccid_hc_tx_delete Dump of assembler code for function ccid_hc_tx_delete:    0xffffffff81a7a3a0 <+0>: test rdi,rdi    0xffffffff81a7a3a3 <+3>: je 0xffffffff81a7a3cd <ccid_hc_tx_delete+45>    0xffffffff81a7a3a5 <+5>: push rbx    0xffffffff81a7a3a6 <+6>: mov rbx,rdi    0xffffffff81a7a3a9 <+9>: mov rdi,rsi    0xffffffff81a7a3ac <+12>: mov rax,QWORD PTR [rbx]    0xffffffff81a7a3af <+15>: mov rdx,QWORD PTR [rax+0x80] <— rax points to a freed object    0xffffffff81a7a3b6 <+22>: test rdx,rdx    0xffffffff81a7a3b9 <+25>: je 0xffffffff81a7a3c0 <ccid_hc_tx_delete+32>    0xffffffff81a7a3bb <+27>: call rdx // <-- arbitrary call    0xffffffff81a7a3bd <+29>: mov rax,QWORD PTR [rbx]    0xffffffff81a7a3c0 <+32>: mov rsi,rbx    0xffffffff81a7a3c3 <+35>: mov rdi,QWORD PTR [rax+0x18]    0xffffffff81a7a3c7 <+39>: pop rbx    0xffffffff81a7a3c8 <+40>: jmp 0xffffffff811fb980 <kmem_cache_free>    0xffffffff81a7a3cd <+45>: repz ret End of assembler dump.
2020-09-01 21:03:08 Thadeu Lima de Souza Cascardo attachment added 0001-dccp-uaf-fix.patch https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1883840/+attachment/5406729/+files/0001-dccp-uaf-fix.patch
2020-09-02 00:22:43 Seth Arnold cve linked 2020-16119
2020-09-16 20:24:03 Thadeu Lima de Souza Cascardo attachment added 0001-UBUNTU-SAUCE-dccp-avoid-double-free-of-ccid-on-child.patch https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1883840/+attachment/5411390/+files/0001-UBUNTU-SAUCE-dccp-avoid-double-free-of-ccid-on-child.patch
2020-11-06 12:18:41 Marc Deslauriers linux (Ubuntu): status New Fix Released
2021-01-14 00:10:34 Avital Ostromich information type Private Security Public Security