
Loongson LA464/LA664 प्रोसेसर में LASX वेक्टर रजिस्टरों के अपरिभाषित उच्च बिट्स के माध्यम से माइक्रोआर्किटेक्चरल डेटा लीक को प्रदर्शित करने वाला प्रूफ-ऑफ-कॉन्सेप्ट, जो ZenBleed के समान है।
LoongBleed एक हार्डवेयर भेद्यता है, जो अवधारणात्मक रूप से ZenBleed (CVE-2023-20593) के समान है — यह Loongson LA464/LA664 प्रोसेसरों को प्रभावित करती है जो LSX (128-बिट SIMD) और LASX (256-बिट SIMD) दोनों को लागू करते हैं।
LoongArch पर, LSX $vr रजिस्टर (128-बिट) LASX $xr रजिस्टर (256-बिट) के निचले आधे हिस्से के उपनाम (alias) हैं। LSX निर्देश और बुनियादी फ़्लोटिंग-पॉइंट संक्रियाएँ केवल निचले 128 बिट्स (या उसके एक उपसमुच्चय) पर कार्य करने के लिए परिभाषित हैं; संबंधित $xr रजिस्टर के ऊपरी बिट्स अपरिभाषित हैं। हालाँकि, एक माइक्रोआर्किटेक्चरल खामी के कारण, ये संक्रियाएँ $xr के ऊपरी 128 बिट्स के माध्यम से डेटा लीक कर सकती हैं, जिससे संवेदनशील डेटा विशेषाधिकार सीमाओं के आर-पार या SMT सहोदरों के बीच उजागर हो जाता है।
स्वतंत्र खोज पर नोट — यही अंतर्निहित हार्डवेयर खामी CISPA Helmholtz Center for Information Security के शोधकर्ताओं द्वारा स्वतंत्र रूप से खोजी और LoongLeak के रूप में प्रकाशित की गई थी (https://loongleakattack.com/), जिसे USENIX Security 2026 में "LoongLeak: Architectural Cross-Privilege-Boundary Data Leakage on LoongArch CPUs" के रूप में प्रस्तुत किया गया। हमारा कार्य LoongLeak टीम से स्वतंत्र रूप से विकसित किया गया था; दोनों समूह इसी निष्कर्ष पर पहुँचे कि Loongson LA464/LA664 प्रोसेसर LASX
$xrरजिस्टरों के अपरिभाषित ऊपरी बिट्स के माध्यम से डेटा लीक करते हैं। ध्यान दें कि लीक को ट्रिगर करने के लिए हम जिन निर्देशों का उपयोग करते हैं, वे LoongLeak पेपर में बताए गए निर्देशों के समान नहीं हैं: हमारा PoC उसी अंतर्निहित हार्डवेयर खामी को पुन: उत्पन्न करने के लिए गैजेट्स के एक भिन्न समूह (vor.v,vld,fld.d,fld.s) पर निर्भर करता है। इसके अलावा, चूँकि लीक कोvor.vजैसे शुद्ध रजिस्टर-रजिस्टर निर्देशों द्वारा ट्रिगर किया जा सकता है (जिसमें कोई मेमोरी लोड शामिल नहीं है), हमारा विश्लेषण सुझाव देता है कि मूल कारण संभवतः भौतिक रजिस्टर पुन: उपयोग है: पुन: उपयोग किए गए भौतिक रजिस्टर के ऊपरी बिट्स साफ़ नहीं किए जाते, जिससे पिछले रजिस्टर धारक से पुराना डेटा लीक हो जाता है। यह LoongLeak पेपर के विश्लेषण से भिन्न है, जो लीक हुए डेटा का कारण L1 डेटा कैश को मानता है।
प्रूफ-ऑफ-कॉन्सेप्ट निम्नानुसार काम करता है:
xvld के माध्यम से एक $xrN रजिस्टर में सभी-शून्य डेटा लोड करें।xvst के माध्यम से पूर्ण 256-बिट रजिस्टर को वापस संग्रहीत करें।PoC इस गैजेट को भौतिक कोरों पर पिन किए गए थ्रेड्स पर 16 आर्किटेक्चरल वेक्टर रजिस्टरों ($xr0–$xr15) में बार-बार चलाता है। निर्देश के बाद प्रकट होने वाले गैर-शून्य मान इंगित करते हैं कि माइक्रोआर्किटेक्चर ने पुराने या क्रॉस-कॉन्टेक्स्ट डेटा को आर्किटेक्चरल रजिस्टर स्थिति में प्रसारित कर दिया है।
PoC कई परीक्षण निर्देशों का समर्थन करता है, जिन्हें --gadget के माध्यम से चुना जा सकता है:
LA664 पर, सभी चार गैजेट्स लीक को उजागर करते हैं, प्रति वेक्टर अधिकतम 192 बिट्स लीक करते हैं। LA464 पर, vld, fld.d, और fld.s लीक करते हैं (प्रति वेक्टर अधिकतम 224 बिट्स); डिफ़ॉल्ट vor.v गैजेट LA464 पर लीक नहीं करता।
Usage: ./loongbleed_poc [OPTIONS]
Options:
-a, --all Launch one thread pinned to each physical core.
By default only thread on CPU 0 is launched.
-g, --gadget [vor|vld|fld.d|fld.s]
Use different instructions for testing.
-h, --help Show this help and exit.
# Single-thread mode on CPU 0
./run.sh
# Single-thread mode with vld gadget (required for LA464)
./run.sh --gadget vld
# All physical cores, default gadget
./run.sh -a
# All cores with fld.d gadget
./run.sh --all --gadget fld.d
एक विक्टिम थ्रेड एक लॉजिकल CPU पर संवेदनशील डेटा संसाधित करता है जबकि PoC अपने SMT सहोदर पर रजिस्टरों की जाँच करता है। स्नूपिंग थ्रेड लीक हुए ऊपरी बिट्स में विक्टिम के डेटा के अंशों को देख सकता है।
# Terminal 1 — start LoongBleed on CPU 0
./run.sh
# Terminal 2 — victim workload on the SMT sibling (CPU 1)
while true; do numactl -C 1 sort < /etc/shadow > /dev/null; done
स्वचालित सेटअप के लिए, प्रदान की गई स्क्रिप्ट का उपयोग करें:
./poc_la664.sh
यह CPU 1 (CPU 0 का SMT सहोदर) पर एक sort वर्कलोड शुरू करता है और डिफ़ॉल्ट गैजेट के साथ CPU 0 पर LoongBleed लॉन्च करता है।
एक विक्टिम थ्रेड एक CPU पर संवेदनशील डेटा संसाधित करता है जबकि PoC उसी कोर पर रजिस्टरों की जाँच करता है। --gadget vld आवश्यक है क्योंकि डिफ़ॉल्ट vor.v गैजेट LA464 पर लीक नहीं करता।
# Terminal 1 — start LoongBleed on CPU 0
./run.sh --gadget vld
# Terminal 2 — victim workload on the same core
while true; do numactl -C 0 sort < /etc/shadow > /dev/null; done
स्वचालित सेटअप के लिए:
./poc_la464.sh
यह CPU 0 पर एक sort वर्कलोड शुरू करता है और --gadget vld के साथ LoongBleed लॉन्च करता है।
PoC एक एकल-फ़ाइल C++ प्रोग्राम है जिसमें कोई बाहरी निर्भरता नहीं है।
g++ -std=c++11 -O2 -march=native -pthread -o loongbleed_poc loongbleed_poc.cpp
या प्रदान की गई स्क्रिप्ट का उपयोग करें:
./run.sh
# or, on LA464:
./run.sh --gadget vld
जब एक लीक का पता चलता है और लीक हुए बाइट्स में कम से कम 8 सतत प्रिंटेबल ASCII वर्णों (0x20–0x7e) का एक क्रम होता है, तो PoC प्रिंट करता है:
[cpu 0] LEAK chunk=14 data=0x7461646e756f4620_6572617774666f53_0000000000000000_0000000000000000 ascii=............Software Foundat
$xr0–$xr15) में से किसने ट्रिगर किया$xrN से वापस पढ़ा गया पूर्ण 256-बिट मान, जिसे data3_data2_data1_data0 के रूप में प्रदर्शित किया जाता है जहाँ:
data0 = बिट्स [63:0] (परिणाम के न्यूनतम 64 बिट्स)data1 = बिट्स [127:64] (निचले 128-बिट आधे के ऊपरी 64 बिट्स)data2 = बिट्स [191:128] (ऊपरी 128-बिट आधे के निचले 64 बिट्स)data3 = बिट्स [255:192] (ऊपरी 128-बिट आधे के ऊपरी 64 बिट्स). के रूप में दिखाया जाता है।ऊपरी 128 बिट्स (data2 या data3) में कोई भी गैर-शून्य मान माइक्रोआर्किटेक्चरल डेटा लीक को इंगित करता है।
यह भेद्यता Chips and Cheese लेख "Loongson's LSX and LASX Vector Extensions" पढ़ते समय खोजी गई थी। लेख में उल्लेख किया गया था कि वेक्टर निर्देश कुछ यादृच्छिक डेटा अवशेष पीछे छोड़ सकते हैं। इससे हमें यह परिकल्पना करने के लिए प्रेरणा मिली कि रजिस्टर रीनेमिंग रजिस्टरों को साफ़ नहीं कर सकती है — जो ZenBleed के समान एक तंत्र है — जो सैद्धांतिक रूप से कर्नेल-स्पेस डेटा लीक करने की अनुमति देगा। फिर हमने इस परिकल्पना को सत्यापित करने के लिए प्रयोग किए; लीक वास्तव में होता है और Loongson 3A5000 और 3A6000 दोनों पर पुन: उत्पन्न होता है।
यह परियोजना केवल शैक्षिक और सुरक्षा अनुसंधान उद्देश्यों के लिए प्रदान की गई है।
| Gadget | Instruction | Description | Leaks on LA664 | Leaks on LA464 |
|---|
vor | vor.v $vrN, $vrN, $vrN | Bitwise OR of $vrN with itself | Yes | No |
vld | vld $vrN, … | 128-bit load from memory into $vrN | Yes | Yes |
fld.d | fld.d $fN, … | 64-bit floating-point load into $fN (alias of $vrN low 64 bits) | Yes | Yes |
fld.s | fld.s $fN, … | 32-bit floating-point load into $fN (alias of $vrN low 32 bits) | Yes | Yes |