• ผู้ใช้ภายในเครื่องที่ไม่มีสิทธิพิเศษ สามารถเชื่อม authencesn, AF_ALG, splice() เพื่อสร้างการ เขียน 4 ไบต์ลง page cache ของไฟล์ที่อ่านได้ และยกระดับสิทธิ์ไปจนถึง root ได้
  • ทำงานได้เหมือนกันบน Linux หลายดิสทริบิวชันด้วย สคริปต์ Python ขนาด 732 ไบต์ เพียงไฟล์เดียว โดยไม่ต้องพึ่ง offset เฉพาะเคอร์เนลหรือ race condition และใช้ exploit เดียวกันเพื่อให้ได้ root shell
  • ขอบเขตผลกระทบครอบคลุม ดิสทริบิวชัน Linux หลักเกือบทั้งหมด ที่ยังไม่แพตช์ และเนื่องจาก AF_ALG เปิดใช้งานในค่าตั้งต้น จึงเปิดช่องมาตั้งแต่ปี 2017 จนถึงช่วงที่ออกแพตช์
  • ในโฮสต์แบบ multi-tenant, Kubernetes / คลัสเตอร์คอนเทนเนอร์, CI runner และ Cloud SaaS ที่รันโค้ดผู้ใช้ บัญชีธรรมดาหรือ pod เดียวอาจนำไปสู่สิทธิ์ root บนโฮสต์ได้ จึงควรเร่งแพตช์ก่อน
  • วิธีรับมืออันดับแรกคือ แพตช์เคอร์เนล ที่มี mainline commit a664bf3d603d และก่อนจะแพตช์ควรปิด algif_aead พร้อม บล็อก AF_ALG สำหรับ workload ที่ไม่น่าเชื่อถือ

ภาพรวมช่องโหว่

  • ความผิดพลาดเชิงตรรกะแบบ เส้นตรงเพียงจุดเดียว เมื่อเชื่อมกับ authencesn, AF_ALG, splice() สามารถนำไปสู่การ เขียน 4 ไบต์ลง page cache และทำให้เกิดการยกระดับสิทธิ์ภายในเครื่องได้
  • ใช้งานได้เหมือนกันกับ Linux ดิสทริบิวชันจำนวนมากที่ออกตั้งแต่ปี 2017 เป็นต้นมา ด้วย สคริปต์ Python ขนาด 732 ไบต์ เพียงไฟล์เดียว โดยไม่ต้องมี offset เฉพาะเคอร์เนลหรือ race window
  • exploit binary เดียวกันสามารถใช้เพื่อให้ได้ root shell บนหลายดิสทริบิวชันโดยไม่ต้องแก้ไข
  • ต้องการเพียงบัญชี local ที่ไม่มีสิทธิพิเศษเท่านั้น ไม่ต้องเข้าถึงเครือข่าย ไม่ต้องมีความสามารถด้าน kernel debugging และไม่ต้องมี primitive อื่นติดตั้งไว้ล่วงหน้า

ขอบเขตผลกระทบ

  • ดิสทริบิวชัน Linux หลักเกือบทั้งหมด ที่ใช้เคอร์เนลซึ่งยังไม่แพตช์อยู่ในขอบเขตผลกระทบ
  • เพราะ AF_ALG ของ kernel crypto API ถูกเปิดไว้โดยปริยายในแทบทุกดิสทริบิวชันกระแสหลัก ระบบจึงเปิดรับช่องโหว่นี้โดยตรงตั้งแต่ปี 2017 จนถึงเวลาที่มีแพตช์
  • ดิสทริบิวชันที่ตรวจสอบโดยตรงแล้วได้แก่ Ubuntu 24.04 LTS, Amazon Linux 2023, RHEL 14.3 และ SUSE 16
  • Debian, Arch, Fedora, Rocky, Alma, Oracle รวมถึงสาย embedded ก็ได้รับผลกระทบเช่นกันหากใช้เคอร์เนลที่ได้รับผลกระทบ

สภาพแวดล้อมที่ควรเร่งแพตช์ก่อน

  • บน โฮสต์ Linux แบบ multi-tenant ผู้ใช้หลายรายแชร์เคอร์เนลเดียวกัน ทำให้บัญชีผู้ใช้ธรรมดาสามารถกลายเป็น root ได้โดยตรง
  • ใน Kubernetes / คลัสเตอร์คอนเทนเนอร์ page cache ถูกแชร์ทั้งโฮสต์ ดังนั้น pod เดียวอาจยึด node และข้ามขอบเขตผู้เช่าได้
  • ใน CI runner และ build farm โค้ดจาก PR ที่ไม่น่าเชื่อถือซึ่งรันด้วยสิทธิ์ผู้ใช้ธรรมดา อาจยกระดับเป็น root บน runner ได้
  • ใน Cloud SaaS ที่รันโค้ดผู้ใช้ คอนเทนเนอร์หรือสคริปต์ที่ผู้เช่าอัปโหลดอาจนำไปสู่ root บนโฮสต์ได้
  • เซิร์ฟเวอร์แบบ single-tenant มีลักษณะเป็น LPE ภายในเป็นหลัก และอาจเชื่อมกับเว็บ RCE หรือ credential ที่ถูกขโมยมาได้
  • โน้ตบุ๊กและเวิร์กสเตชันผู้ใช้คนเดียวมีความเร่งด่วนน้อยกว่า แต่การรันโค้ดในเครื่องก็ยังอาจนำไปสู่การยกระดับเป็น root ได้

PoC ที่เผยแพร่และวิธีใช้งาน

  • มีการเผยแพร่ PoC เพื่อให้ฝั่งป้องกันใช้ตรวจสอบระบบและยืนยันแพตช์จากผู้จำหน่ายได้
  • copy_fail_exp.py ใช้เพียงไลบรารีมาตรฐานของ Python 3.10+ ได้แก่ os, socket, zlib
  • เป้าหมายตั้งต้นคือ /usr/bin/su และสามารถส่ง setuid binary อื่นผ่าน argv[1] ได้
  • มันแก้ไข setuid binary ภายใน page cache และแม้การเปลี่ยนแปลงจะไม่คงอยู่หลังรีบูต แต่ root shell ที่ได้มาสามารถใช้งานได้จริง
  • Issue tracker

วิธีบรรเทา

  • สิ่งสำคัญอันดับแรกคือ แพตช์เคอร์เนล โดยต้องอัปเดตไปใช้เคอร์เนลดิสทริบิวชันที่รวม mainline commit a664bf3d603d แล้ว
  • แพตช์นี้ย้อนการเพิ่มประสิทธิภาพแบบ in-place ของ algif_aead ที่ถูกนำเข้ามาตั้งแต่ปี 2017 เพื่อไม่ให้หน้า page cache เข้าไปอยู่ใน writable destination scatterlist
  • ก่อนมีแพตช์ แนะนำให้ ปิดโมดูล algif_aead
    • echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
    • rmmod algif_aead 2>/dev/null || true
  • ในคอนเทนเนอร์ sandbox และ CI ที่รัน workload ที่ไม่น่าเชื่อถือ ควร บล็อกการสร้าง socket AF_ALG ด้วย seccomp ไม่ว่าจะมีแพตช์แล้วหรือไม่ก็ตาม

ผลกระทบเมื่อปิดใช้งาน

  • สำหรับระบบส่วนใหญ่ แทบไม่มีผลกระทบที่วัดได้
  • dm-crypt / LUKS, kTLS, IPsec/XFRM, in-kernel TLS, OpenSSL/GnuTLS/NSS แบบ build ปกติ, SSH และ kernel keyring crypto ไม่ได้รับผลกระทบ
    • สิ่งเหล่านี้ใช้ kernel crypto API โดยตรงและไม่ได้ผ่านเส้นทาง AF_ALG
  • หากเปิดใช้เอนจิน afalg ใน OpenSSL แบบชัดเจน, ใช้เส้นทาง embedded crypto offloading บางแบบ หรือมีแอปพลิเคชันที่ bind socket aead/skcipher/hash โดยตรง ก็อาจได้รับผลกระทบ
    • ตรวจสอบได้ด้วย lsof | grep AF_ALG หรือ ss -xa
  • การปิด AF_ALG จะไม่ทำให้เป้าหมายที่เดิมไม่ได้เรียกใช้งานมันช้าลง และเป้าหมายที่ใช้งานอยู่จะย้อนกลับไปใช้ไลบรารีเข้ารหัสใน userspace ตามปกติ

จุดที่ต่างจาก Linux LPE ทั่วไป

  • ต่างจาก Linux LPE ทั่วไปตรงที่ ไม่มี race condition และไม่ต้องใช้ offset แยกตามดิสทริบิวชัน
  • ยังระบุว่ามีความน่าเชื่อถือ ยิงครั้งเดียวสำเร็จ 100% และครอบคลุมช่วงเวลายาวตั้งแต่ปี 2017 ถึง 2026 ไม่ใช่แค่ช่วงเวอร์ชันเคอร์เนลแคบ ๆ
  • ด้วยขนาดเพียง 732 ไบต์ และใช้แค่ไลบรารีมาตรฐานของ Python จึงไม่ต้องมี payload ที่คอมไพล์แล้วหรือ dependency เพิ่มเติม
  • เส้นทางการเขียน ข้าม VFS และ page ที่ถูกทำให้เสียหายจะไม่ถูกทำเครื่องหมาย dirty จึงไม่มีการเขียนอะไรลงดิสก์
  • เนื่องจาก page cache ถูกแชร์ทั้งโฮสต์ มันจึงทำงานได้มากกว่าแค่ LPE ธรรมดา แต่ยังเป็น primitive สำหรับ container escape ได้ด้วย

หลักการทำงานและลักษณะการตรวจจับ

  • ผู้ใช้ภายในเครื่องที่ไม่มีสิทธิพิเศษสามารถเขียน 4 ไบต์ที่ควบคุมได้ลงใน page cache ของไฟล์ที่อ่านได้ บนระบบ Linux และนำไปใช้เพื่อให้ได้สิทธิ์ root
  • เป้าหมายคือ page cache ในหน่วยความจำ ไม่ใช่ไฟล์จริงบนดิสก์ และถ้าแก้สำเนาในแคชของ /usr/bin/su จากมุมมองของ execve ก็เทียบเท่ากับการเปลี่ยนตัวไบนารีเอง
  • เพราะไม่มีการเปลี่ยนแปลงบนดิสก์ inotify จึงไม่แจ้งเตือน และหลังรีบูตหรือเมื่อ cache ถูกขับออก ไฟล์ต้นฉบับจะถูกโหลดกลับมาใหม่
  • เครื่องมือแฮชทั่วไปอย่าง sha256sum, AIDE, Tripwire จะอ่าน page cache ผ่าน read() ดังนั้น ตราบใดที่ความเสียหายยังคงอยู่ในแคช ค่าแฮชอาจไม่ตรงกับค่าอ้างอิง
  • เมื่อ cache ถูกขับออกหรือรีบูต ค่าแฮชจะกลับมาตรงกับต้นฉบับอีกครั้ง และใน forensic image ของดิสก์ก็จะเหลือเพียงไฟล์ที่ยังไม่ถูกแก้ไข
  • ใน IMA appraisal enforcing mode หากเปิด every-read measurement ก็สามารถตรวจจับได้ที่จุด execve ก่อนที่ไบนารีที่เสียหายจะถูกรัน

ความต่างจากช่องโหว่อื่น

  • อยู่ในตระกูลเดียวกับ Dirty Pipe ตรงที่ userspace ที่ไม่มีสิทธิพิเศษสามารถทำให้ page cache เสียหายและเขียนลง setuid binary เพื่อเอา root ได้โดยไม่เปลี่ยนข้อมูลบนดิสก์
  • แต่กลไกต่างกัน โดย Dirty Pipe ใช้ประโยชน์จาก pipe buffer flags ส่วน Copy Fail ใช้ประโยชน์จาก AEAD scratch write ที่ข้ามขอบเขต chained scatterlist
  • Dirty Pipe ต้องอาศัยเคอร์เนล 5.8 ขึ้นไปที่มีแพตช์บางตัวเข้าไปแล้ว แต่ Copy Fail ครอบคลุมช่วงตั้งแต่ปี 2017 ถึง 2026
  • ต่างจาก Dirty Cow ตรงที่ไม่ต้องชนะ COW race แบบ TOCTOU ไม่ต้องลองหลายครั้ง และไม่ทำให้ระบบไม่เสถียร

รายละเอียดเพิ่มเติม

  • /usr/bin/su ไม่ใช่ข้อบังคับ หากเป็น setuid-root binary ที่ผู้ใช้อ่านได้ ก็ใช้กับ passwd, chsh, chfn, mount, sudo, pkexec ได้เช่นกัน
  • ไม่ใช่ช่องโหว่ระยะไกล และต้องมี การรันโค้ดในเครื่องด้วยสิทธิ์ผู้ใช้ทั่วไป ก่อน
  • หากเว็บ RCE ตกมาที่บัญชีบริการที่ไม่มีสิทธิพิเศษ หรือเชื่อมกับ SSH foothold, PR อันตรายบน CI runner ก็สามารถนำไปสู่ root ได้
  • แพตช์จะย้อนการเพิ่มประสิทธิภาพแบบ in-place ของ algif_aead ทำให้ req->src และ req->dst กลับไปเป็น scatterlist ที่แยกกัน
  • หน้า page cache จะคงอยู่เฉพาะใน source แบบอ่านอย่างเดียว ส่วนปลายทางที่ crypto เขียนได้จะเหลือเพียง user buffer

กำหนดการเปิดเผยและข้อมูลติดตาม

  • 2026-03-23 มีการรายงานไปยังทีมความปลอดภัยของ Linux kernel
  • 2026-03-24 มีการยืนยันเบื้องต้น
  • 2026-03-25 มีการเสนอและทบทวนแพตช์
  • 2026-04-01 แพตช์ถูก commit เข้า mainline
  • 2026-04-22 มีการกำหนด CVE-2026-31431
  • 2026-04-29 เปิดเผยที่ https://copy.fail/
  • บทวิเคราะห์ทางเทคนิคจาก Xint blog
    • มี root cause, แผนภาพ scatterlist, ลำดับเหตุการณ์ปี 2011→2015→2017 และ walkthrough ของ exploit
    • Part 2 ที่จะพูดถึงการหนีออกจากคอนเทนเนอร์ใน Kubernetes จะเผยแพร่ภายหลัง

ข้อมูลเกี่ยวกับ Xint Code

  • ค้นพบด้วยวิธี AI-assisted โดยจุดตั้งต้นคือการวิจัยของมนุษย์ที่ตั้งข้อสังเกตว่า splice() ส่งหน้า page cache เข้าไปยัง crypto subsystem และแหล่งที่มาของ page ใน scatterlist อาจเป็นคลาสบั๊กที่ยังถูกสำรวจไม่มาก
  • จากนั้น Xint Code ได้ขยายการตรวจสอบไปยัง subsystem crypto/ ทั้งหมดของ Linux ในระดับเวลาประมาณ 1 ชั่วโมง และรายการที่ ร้ายแรงที่สุด จากผลลัพธ์นั้นก็คือ Copy Fail
  • Xint Code
    • Xint blog write-up
    • จากการสแกนเดียวกันยังพบบั๊กความเสี่ยงสูงอื่น ๆ อีก ซึ่งยังอยู่ระหว่าง coordinated disclosure

ยังไม่มีความคิดเห็น

ยังไม่มีความคิดเห็น