প্রকল্পের অন্তর্ভুক্ত সমাবেশ ফাইল অন্তর্ভুক্ত যখন এমএমএপ থেকে অপ্রত্যাশিত নির্বাহী অনুমতি


94

আমি এই দিয়ে দেয়ালে মাথা ঠেস দিচ্ছি।

আমার প্রকল্পে, যখন আমি mmapম্যাপিংয়ের সাথে মেমরি বরাদ্দ করি ( /proc/self/maps) দেখায় যে আমি কেবল পঠনযোগ্য মেমরির অনুরোধ করা সত্ত্বেও এটি একটি পঠনযোগ্য এবং কার্যকরযোগ্য অঞ্চল ।

স্ট্রেস (যা দেখতে ভাল লাগছিল) এবং অন্যান্য ডিবাগিংয়ের পরে, আমি এই একমাত্র জিনিসটি সনাক্ত করতে সক্ষম হয়েছি যা এই অদ্ভুত সমস্যাটি এড়াতে পারে বলে মনে করে: প্রকল্প থেকে সমাবেশ ফাইলগুলি সরিয়ে এবং কেবল খাঁটি সি ছেড়ে চলে যায় (কী ?!)

সুতরাং এখানে আমার অদ্ভুত উদাহরণ, আমি উবুনবতু 19.04 এবং ডিফল্ট জিসিসিতে কাজ করছি।

যদি আপনি এএসএম ফাইলের সাথে এক্সিকিউটেবল লক্ষ্যটি সংকলন করেন (যা খালি) তবে আপনি mmapএকটি পাঠযোগ্য এবং এক্সিকিউটেবল অঞ্চলটি ফিরিয়ে দেন, আপনি যদি তৈরি না করেন তবে এটি সঠিকভাবে আচরণ করে ve /proc/self/mapsআমার উদাহরণটিতে আমি যে ফলাফলটি এম্বেড করেছি তা দেখুন ।

example.c

#include <stdio.h>
#include <string.h>
#include <sys/mman.h>

int main()
{
    void* p;
    p = mmap(NULL, 8192,PROT_READ,MAP_ANONYMOUS|MAP_PRIVATE,-1,0);

    {
        FILE *f;
        char line[512], s_search[17];
        snprintf(s_search,16,"%lx",(long)p);
        f = fopen("/proc/self/maps","r");
        while (fgets(line,512,f))
        {
            if (strstr(line,s_search)) fputs(line,stderr);
        }

        fclose(f);
    }

    return 0;
}

উদাহরণ.s : একটি খালি ফাইল!

আউটপুট

এএসএম সহ সংস্করণ অন্তর্ভুক্ত

VirtualBox:~/mechanics/build$ gcc example.c example.s -o example && ./example
7f78d6e08000-7f78d6e0a000 r-xp 00000000 00:00 0 

এএসএম ছাড়া সংস্করণ অন্তর্ভুক্ত

VirtualBox:~/mechanics/build$ gcc example.c -o example && ./example
7f1569296000-7f1569298000 r--p 00000000 00:00 0 

5
এটি মারাত্মক অদ্ভুত।
ফুজ

6
আমি এটি কেবল জিসিসি (সিএমকে নেই) দিয়ে পুনরুত্পাদন করতে সক্ষম হয়েছি, তাই উদাহরণটি আরও ন্যূনতম করার জন্য আমি প্রশ্নটি সম্পাদনা করেছি।
জোসেফ সিবিল-রিইনস্টেট মনিকা

2
সম্ভবত সংশ্লিষ্ট stackoverflow.com/questions/32730643/...
সামি Kuhmonen

আপনি ঠিকই বলেছেন, তার উত্তরটির অংশটি READ_IMPLIES_EXEC ব্যক্তির কাছাকাছি থাকতে হবে
বেন হির্সবার্গ

আপনার উত্স ফাইলগুলি এর সাথে জমা দিন -Wa,--noexecstack
jww

উত্তর:


90

লিনাক্স একটি হয়েছে মৃত্যুদন্ড ডোমেইন নামক READ_IMPLIES_EXEC, যা দিয়ে বরাদ্দ সকল পৃষ্ঠা ঘটায় PROT_READএছাড়াও দেওয়া PROT_EXEC। এটি নিজের জন্য সক্ষম কিনা তা এই প্রোগ্রামটি আপনাকে দেখাবে:

#include <stdio.h>
#include <sys/personality.h>

int main(void) {
    printf("Read-implies-exec is %s\n", personality(0xffffffff) & READ_IMPLIES_EXEC ? "true" : "false");
    return 0;
}

আপনি যদি খালি .sফাইলের সাথে এটি সঙ্কলন করেন তবে দেখতে পাবেন এটি সক্ষম হয়েছে, তবে একটি ছাড়া এটি অক্ষম হয়ে যাবে। এর প্রাথমিক মানটি আপনার বাইনারিতে ELF মেটা-তথ্য থেকে আসে । কি readelf -Wl example। খালি .sফাইল ব্যতীত সংকলন করার সময় আপনি এই লাইনটি দেখতে পাবেন :

  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10

আপনি এটি সংকলন করার সময় এটি একটি:

  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RWE 0x10

ন্যায়বিচারের RWEপরিবর্তে নোট করুন RW। এর কারণ হ'ল লিঙ্কারটি ধরে নিয়েছে যে আপনার সমাবেশ ফাইলগুলি পড়ার জন্য প্রয়োগ করা আবশ্যক - যদি না এটি স্পষ্টভাবে না বলা হয় যে তারা না করে, এবং যদি আপনার প্রোগ্রামের কোনও অংশে রিড-ইমপ্লাই-এক্সিকিউটের প্রয়োজন হয়, তবে এটি আপনার সম্পূর্ণ প্রোগ্রামের জন্য সক্ষম করা হয়েছে । জিসিসি সংকলিত যে অ্যাসেম্বলি ফাইলগুলি এটি বলে যে এটি এই লাইনের সাথে এটির প্রয়োজন নেই (আপনি এটি সংকলন করলে আপনি এটি দেখতে পাবেন -S):

        .section        .note.GNU-stack,"",@progbits

এই লাইনটি ভিতরে রাখুন example.s, এবং এটি লিঙ্কারে বলবে যে এটিরও প্রয়োজন হয় না এবং আপনার প্রোগ্রামটি তখন প্রত্যাশা অনুযায়ী কাজ করবে।


13
পবিত্র বোকা, এটি একটি অদ্ভুত ডিফল্ট। আমার ধারণা, নোেক্সেকের আগে এই সরঞ্জামচেনটির অস্তিত্ব ছিল, এবং নেক্সেক্সকে ডিফল্ট করে তোলার ফলে ভাঙা জিনিস থাকতে পারে। এখন আমি কৌতূহল করছি যে অন্যান্য ন্যাসেম / ইএএসএম এর মতো সমাবেশকারীরা কীভাবে .oফাইল তৈরি করেন ! তবে যাইহোক, আমি অনুমান করি এটি হ'ল প্রক্রিয়া যা gcc -zexecstackব্যবহার করে এবং কেন এটি কেবল স্ট্যাককেই নয়, সমস্ত কিছু কার্যকর করতে সক্ষম হয়।
পিটার কর্ডস

23
@ পিটার - এজন্য বোটান, ক্রিপ্টো ++ এবং ওপেনএসএসএল-এর মতো প্রকল্পগুলি, যা এসেম্ব্লার ব্যবহার করে, যোগ করে -Wa,--noexecstack। আমি মনে করি এটি একটি খুব বাজে ধারালো প্রান্ত। এনএক্স-স্ট্যাকের নীরব ক্ষতি একটি সুরক্ষার দুর্বলতা হওয়া উচিত। বিন্টিল লোকেরা এটি ঠিক করতে হবে।
jww

14
@jww এটি সত্যিই একটি সুরক্ষা সমস্যা, আশ্চর্যজনক যে এটির আগে কেউ এর আগে রিপোর্ট করেনি
বেন হির্সবার্গ

4
+1, তবে এই উত্তরটি আরও ভাল হবে যদি লাইনটির অর্থ / যুক্তিটি .note.GNU-stack,"",@progbitsব্যাখ্যা করা হত - এখনই এটি অস্বচ্ছ, "অক্ষরের এই ম্যাজিক স্ট্রিংটি এই প্রভাবের কারণ হয়" এর সমতুল্য, তবে স্ট্রিংটি পরিষ্কারভাবে দেখে মনে হচ্ছে এটির কোনও ধরণের রয়েছে শব্দার্থবিদ্যা।
এমট্রেসিয়র

33

জিএনইউ-নির্দিষ্ট বিভাগের নির্দেশিকা বৈকল্পিকের সাথে আপনার অ্যাসেম্বলি ফাইলগুলিকে সংশোধন করার বিকল্প হিসাবে, আপনি -Wa,--noexecstackঅ্যাসেম্বলি ফাইলগুলি তৈরির জন্য আপনার কমান্ড লাইনে যুক্ত করতে পারেন । উদাহরণস্বরূপ, আমি কীভাবে এটি মসলেসের মধ্যে করব তা দেখুন configure:

https://git.musl-libc.org/cgit/musl/commit/configure?id=adefe830dd376be386df5650a09c313c483adf1a

আমি বিশ্বাস করি ইন্টিগ্রেটেড-এসেমব্লারারের সাথে কমপক্ষে কিছু ঝাঁকুনির জন্য এটি --noexecstack(ব্যতীত -Wa) হিসাবে পাস করার প্রয়োজন হতে পারে , সুতরাং আপনার কনফিগার স্ক্রিপ্টটি সম্ভবত উভয় পরীক্ষা করে দেখতে হবে এবং কোনটি গ্রহণযোগ্য তা দেখতে হবে।

একই ফলাফল পেতে -Wl,-z,noexecstackআপনি লিংক টাইমে (ইন LDFLAGS) ব্যবহার করতে পারেন । এর অসুবিধাটি হ'ল এটি যদি আপনার প্রকল্পটি .aঅন্যান্য সফ্টওয়্যার দ্বারা ব্যবহারের জন্য স্থিতিশীল ( ) লাইব্রেরি ফাইল তৈরি করে তবে এটি কার্যকর হয় না , যেহেতু আপনি তখন লিংক-সময় বিকল্পগুলি অন্য প্রোগ্রামগুলি দ্বারা ব্যবহার করার সময় নিয়ন্ত্রণ করেন না।


1
হুম ... আমি জানতাম না যে আপনি এই পোস্টটি পড়ার আগে ধনী ফেলকার ছিলেন। আপনার প্রদর্শনের নাম দালিয়াস কেন নয়?
এসএস অ্যান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.