
CVE-2026-86547 के लिए स्टैंडअलोन प्रूफ ऑफ कॉन्सेप्ट, जो mrubyc op_enter() में 4.0.0 तक NULL पॉइंटर डीरेफरेंस है।
OP_ENTER NULL पॉइंटर डीरेफ़रेंसCVE-2026-86547 के लिए स्टैंडअलोन प्रूफ़ ऑफ़ कॉन्सेप्ट, जो रिलीज़ 4.0.0 तक mrubyc के op_enter() हैंडलर में NULL पॉइंटर डीरेफ़रेंस है।
mrubyc एम्बेडेड सिस्टम के लिए एक हल्का Ruby कार्यान्वयन है। इसका बाइटकोड VM वर्तमान कॉल-फ़्रेम पॉइंटर को mrbc_vm.callinfo_tail में रखता है। टॉप लेवल पर, mrbc_vm_begin() इस पॉइंटर को NULL पर इनिशियलाइज़ करता है क्योंकि अभी तक कोई मेथड कॉल फ़्रेम मौजूद नहीं होता।
release4.0.0 में कमज़ोर op_enter() कार्यान्वयन में, हैंडलर callinfo->reg_offset को पढ़ता है, बिना पहले यह जाँचे कि vm->callinfo_tail NULL है या नहीं:
mrbc_callinfo *callinfo = vm->callinfo_tail;
int reg_offset = callinfo->reg_offset;
एक तैयार किया गया .mrb बाइटकोड प्रोग्राम OP_ENTER को टॉप लेवल पर रख सकता है, जिससे इंटरप्रेटर इस कोड तक NULL callinfo_tail के साथ पहुँचता है और NULL पॉइंटर डीरेफ़रेंस के माध्यम से क्रैश हो जाता है।
CVE: CVE-2026-86547
प्रकार: CWE-476 — NULL पॉइंटर डीरेफ़रेंस
प्रभाव: उपलब्धता / डिनायल ऑफ़ सर्विस
प्रभावित: mrubyc 4.0.0 तक
गंभीरता: मध्यम, CVSS 6.9 (एडवाइज़री के अनुसार)
यह PoC प्रासंगिक mrbc_callinfo और mrbc_vm लेआउट को दर्शाता है और पूरे mrubyc रनटाइम से स्वतंत्र रूप से कमज़ोर मेमोरी एक्सेस को पुन: उत्पन्न करता है।
यह दो पथ प्रदर्शित करता है:
callinfo_tail NULL है और callinfo->reg_offset को बिना किसी गार्ड के डीरेफ़रेंस किया जाता है, जिससे सेगमेंटेशन फ़ॉल्ट उत्पन्न होता है।OP_ENTER को सुरक्षित रूप से अस्वीकार करती है, इसके बाद एक नियंत्रण परीक्षण यह दिखाता है कि एक वैध कॉल फ़्रेम अभी भी काम करता है।हैर्नेस कमज़ोर पॉइंटर पर volatile और अपने विवरण में __builtin_trap() का उपयोग करता है ताकि रीप्रोड्यूसर सैनिटाइज़र-आधारित अवलोकन के लिए उपयुक्त हो। वास्तविक कमज़ोर एक्सेस callinfo->reg_offset रीड है।
gcc -O0 -g -o poc poc.c
./poc
कमज़ोर पथ पर अपेक्षित परिणाम इसके बाद एक सेगमेंटेशन फ़ॉल्ट है:
[VULNERABLE PATH] op_enter without NULL guard
vm->callinfo_tail = NULL (top-level frame)
About to dereference NULL...
gcc -O0 -g -fsanitize=address -fno-omit-frame-pointer -o poc-asan poc.c
./poc-asan
सैनिटाइज़र को NULL mrbc_callinfo बेस से reg_offset फ़ील्ड के अनुरूप पते पर SEGV रिपोर्ट करना चाहिए। यहाँ उपयोग किए गए स्ट्रक्चर लेआउट के साथ, offsetof(mrbc_callinfo, reg_offset) 0x14 है।
./poc fixed
अपेक्षित आउटपुट में शामिल है:
[FIXED PATH] op_enter with NULL guard
[GUARD] top-level OP_ENTER — rejected safely
[control, valid frame] reg_offset = 5
Fixed path: no crash.
मूल कमज़ोर हैंडलर mrubyc release4.0.0 में src/vm.c में लगभग पंक्ति 1537 पर है। प्रासंगिक ऑपरेशन vm->callinfo_tail को callinfo में असाइन करने के बाद बिना NULL जाँच के callinfo->reg_offset का सीधा डीरेफ़रेंस है।
शोध में संदर्भित फ़िक्स के बाद का स्रोत कमिट 4261cf5e5ae5579e3110dab98a04b91c7d919429 है।
स्टैंडअलोन हैर्नेस अंतर्निहित मेमोरी त्रुटि को प्रदर्शित करता है। mrubyc में ही, ट्रिगर के लिए एक तैयार की गई .mrb बाइटकोड फ़ाइल आवश्यक है जिसमें टॉप लेवल पर, किसी मेथड परिभाषा के बाहर एक OP_ENTER निर्देश हो। यदि कोई एप्लिकेशन अविश्वसनीय .mrb फ़ाइलें लोड और निष्पादित करता है, तो हमलावर-नियंत्रित बाइटकोड फ़ाइल इंटरप्रेटर प्रक्रिया को क्रैश कर सकती है।
यह एक डिनायल-ऑफ़-सर्विस स्थिति है। शोध NULL डीरेफ़रेंस से परे कोड निष्पादन, सूचना प्रकटीकरण, या मेमोरी करप्शन का दावा नहीं करता।
src/vm.csrc/vm.cOP_SUPER NULL-जाँच समस्या जिसने op_enter() के ऑडिट को प्रेरित कियाखोज की कहानी यहाँ प्रलेखित है: I Read Someone Else's Bug Report, Then Found The Same Missing Check In The Next Function Over।
मुख्य शोध अवलोकन यह था कि op_super() में उसी vm->callinfo_tail इनवेरिएंट के आसपास एक अनुपस्थित NULL गार्ड था। पड़ोसी op_enter() हैंडलर की जाँच करने पर पता चला कि वही धारणा वहाँ भी संबंधित गार्ड के बिना मौजूद थी।