.dtors लेखन दिखता है, लेकिन segfault लिखने का प्रयास करता है


9

यह उबंटू 9.04, 2.6.28-11-सर्वर, 32 बिट x86 है


$ cat test.c
main() { int *dt = (int *)0x08049f18; *dt = 1; }
$ readelf -S ./test
...
  [18] .dtors            PROGBITS        08049f14 000f14 000008 00  WA  0   0  4
...
$ ./test
Segmentation fault
$

असिंचित के लिए: gcc एक विध्वंसक खंड बनाता है .dtors, योगिनी निष्पादन योग्य में, जिसे main()बाहर निकलने के बाद कहा जाता है। यह तालिका लंबे समय से लेखन योग्य है, और ऐसा लगता है कि यह मेरे मामले में होना चाहिए ( readelfआउटपुट देखें )। लेकिन मेज पर लिखने का प्रयास एक segfault का कारण बनता है।

मुझे लगता है कि वहाँ एक आंदोलन की ओर जा रहा है आसानी से .dt, plt, हाल ही में मिला है, लेकिन मुझे समझ में नहीं आ रहा है readelfऔर segfault के बीच बेमेल है ।


असली सवाल यह है कि आप यह क्यों चाहते हैं कि यह योग्य हो?
एलेक्स

1
मैं एक सुरक्षा वर्ग सिखा रहा हूं जिसमें कई संवेदनशील कार्यक्रमों को तोड़ना शामिल है, लेकिन एक अभ्यास में शेल्फ़ को निष्पादित करने के लिए .dtors को लिखना शामिल है। यह अब काम नहीं करता है और मैं इस मुद्दे को ट्रैक करने की कोशिश कर रहा हूं।
फिक्स

बेमेल इसलिए है क्योंकि संभवतः कुछ डेटा रिलोकेशन हैं (जिन्हें केवल पढ़ने के लिए चिह्नित करने से पहले ठीक किया जाना चाहिए, और वैसे भी आलसी नहीं किया जा सकता है, इसलिए वहां एक बार स्थिर हो जाएगा)।
नवजाल

जवाबों:


5

उन खंडों को GNU_RELRO (आसानी से स्थानांतरण) के रूप में चिह्नित किया गया है, जिसका अर्थ है कि जैसे ही गतिशील लोडर ने तय किया है (लोड समय पर, वहाँ कोई आलसी स्थान नहीं हैं) सभी स्थानांतरण, यह उन लोगों को केवल पढ़ने के लिए चिह्नित करता है। ध्यान दें कि अधिकांश .got.pltदूसरे पृष्ठ पर है, इसलिए उपचार नहीं मिलता है।

आप लिंकर स्क्रिप्ट देख सकते हैं ld --verbose, यदि आप RELRO खोजते हैं तो आपको कुछ ऐसा मिलेगा:

.got            : { *(.got) }
. = DATA_SEGMENT_RELRO_END (12, .);
.got.plt        : { *(.got.plt) }

जिसका अर्थ है कि RELRO खंड 12 बाइट्स को समाप्त करते हैं .got.plt(गतिशील लिंकर कार्यों के लिए संकेत पहले से ही हल हो गए हैं, इसलिए केवल-पढ़ने के लिए चिह्नित किया जा सकता है)।

कड़े गेंटू प्रोजेक्ट में RELRO के बारे में http://www.gentoo.at/proj/en/hardened/hardened-toolchain.xml#RELRO पर कुछ दस्तावेज हैं ।


5

मैं बता सकता हूं कि यह विफल क्यों हो रहा है, हालांकि मुझे वास्तव में नहीं पता है कि सिस्टम का कौन सा हिस्सा जिम्मेदार है। जबकि .dtorsबाइनरी में चिड़चिड़ा चिह्नित किया गया है, यह ऐसा दिखता है (जैसे .ctors, जीओटी, और कुछ अन्य चीजों के साथ) स्मृति में एक अलग, गैर-लेखन पृष्ठ में मैप किया जा रहा है। मेरे सिस्टम पर, .dtorsडाला जा रहा है 0x8049f14:

$ readelf -S test
  [17] .ctors            PROGBITS        08049f0c 000f0c 000008 00  WA  0   0  4
  [18] .dtors            PROGBITS        08049f14 000f14 000008 00  WA  0   0  4
  [19] .jcr              PROGBITS        08049f1c 000f1c 000004 00  WA  0   0  4
  [20] .dynamic          DYNAMIC         08049f20 000f20 0000d0 08  WA  6   0  4
  [21] .got              PROGBITS        08049ff0 000ff0 000004 04  WA  0   0  4
  [22] .got.plt          PROGBITS        08049ff4 000ff4 00001c 04  WA  0   0  4
  [23] .data             PROGBITS        0804a010 001010 000008 00  WA  0   0  4
  [24] .bss              NOBITS          0804a018 001018 000008 00  WA  0   0  4

यदि मैं निष्पादन योग्य और जांच चलाऊं /proc/PID/maps, तो मैं देखता हूं:

08048000-08049000 r-xp 00000000 08:02 163678     /tmp/test
08049000-0804a000 r--p 00000000 08:02 163678     /tmp/test
0804a000-0804b000 rw-p 00001000 08:02 163678     /tmp/test

.data/ .bssअभी भी अपने स्वयं के पृष्ठ में लिखने योग्य हैं, लेकिन अन्य 0x8049000-0x804a000नहीं हैं। मुझे लगता है कि यह कर्नेल में एक सुरक्षा विशेषता है (जैसा कि आपने कहा, "रीडऑनली। डीडर्स, पीएलटी की ओर एक आंदोलन हुआ है, हाल ही में मिला है"), लेकिन मुझे विशेष रूप से यह नहीं पता है कि इसे क्या कहा जाता है (ओपनबीएसडी में कुछ ऐसा ही कहा जाता है। W ^ X ; लिनक्स में PaX है , लेकिन अधिकांश कर्नेल में नहीं बनाया गया है)

आप इसके साथ प्राप्त कर सकते हैं mprotect, जो आपको पृष्ठ की इन-मेमोरी विशेषताओं को बदलने देता है:

mprotect((void*)0x8049000, 4096, PROT_WRITE);

इसके साथ, मेरा परीक्षण कार्यक्रम क्रैश नहीं होता है, लेकिन अगर मैं किसी अन्य फ़ंक्शन के पते के साथ अंतिम प्रहरी .dtors( 0x8049f18) को अधिलेखित करने का प्रयास करता हूं , तो वह फ़ंक्शन अभी भी निष्पादित नहीं करता है; वह हिस्सा मैं समझ नहीं सकता।

उम्मीद है किसी और को पता है कि पृष्ठ को आसानी से बनाने के लिए क्या जिम्मेदार है, और क्यों संशोधित .dtorsकरना मेरे सिस्टम पर कुछ भी नहीं करता है


3
यदि PaX के साथ ओपी लिनक्स mprotectएक निष्पादन योग्य पृष्ठ को लिखने योग्य नहीं बना सकता है या एक पृष्ठ को निष्पादन योग्य बना सकता है जो इससे पहले तब तक लिखने योग्य था जब तक कि वह सुविधा अक्षम न हो paxctl -m
15

@stribika आह, अच्छा पता करने के लिए
माइकल Mrozek
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.