AArch64 বাইনারিগুলির জন্য এক্সিকিউট-অনলি মেমরি (XOM)

AArch64 সিস্টেম বাইনারিগুলির জন্য এক্সিকিউটেবল কোড বিভাগগুলিকে ডিফল্টরূপে চিহ্নিত করা হয় এক্সিকিউট-অনলি (অ-পঠনযোগ্য) জাস্ট-ইন-টাইম কোড পুনঃব্যবহারের আক্রমণের বিরুদ্ধে কঠোর প্রশমন হিসাবে। কোড যা ডেটা এবং কোড একসাথে মিশ্রিত করে এবং কোড যা উদ্দেশ্যমূলকভাবে এই বিভাগগুলি পরিদর্শন করে (প্রথমে মেমরি বিভাগগুলিকে পাঠযোগ্য হিসাবে পুনরায় ম্যাপ না করে) আর কাজ করে না। 10 এর টার্গেট SDK (API লেভেল 29 বা উচ্চতর) সহ অ্যাপগুলি প্রভাবিত হয় যদি অ্যাপটি প্রথমে পঠনযোগ্য হিসাবে চিহ্নিত না করে মেমরিতে এক্সিকিউট-অনলি মেমরি (XOM) সক্ষম সিস্টেম লাইব্রেরির কোড বিভাগগুলি পড়ার চেষ্টা করে।

এই প্রশমন থেকে সম্পূর্ণরূপে উপকৃত হতে, উভয় হার্ডওয়্যার এবং কার্নেল সমর্থন প্রয়োজন। এই সমর্থন ছাড়া, প্রশমন শুধুমাত্র আংশিকভাবে প্রয়োগ করা যেতে পারে. ARMv8.2 ডিভাইসে এর জন্য সম্পূর্ণ সমর্থন প্রদান করার জন্য Android 4.9 সাধারণ কার্নেলে উপযুক্ত প্যাচ রয়েছে।

বাস্তবায়ন

কম্পাইলার দ্বারা উত্পন্ন AArch64 বাইনারিগুলি অনুমান করে যে কোড এবং ডেটা মিশ্রিত নয়। এই বৈশিষ্ট্যটি সক্রিয় করা ডিভাইসের কর্মক্ষমতাকে নেতিবাচকভাবে প্রভাবিত করে না।

যে কোডের জন্য তার এক্সিকিউটেবল সেগমেন্টে ইচ্ছাকৃত মেমরির অন্তর্নিদর্শন করতে হয়, সেগুলিকে পঠনযোগ্য করার অনুমতি দেওয়ার জন্য পরিদর্শনের প্রয়োজন হয় এমন কোডের সেগমেন্টগুলিতে mprotect কল করার পরামর্শ দেওয়া হয়, তারপর পরিদর্শন সম্পূর্ণ হলে পঠনযোগ্যতা সরিয়ে দিন।
এই ইমপ্লিমেন্টেশনের ফলে মেমরি সেগমেন্টে রিড হয় যা শুধুমাত্র এক্সিকিউট হিসেবে চিহ্নিত করা হয় যার ফলে সেগমেন্টেশন ফল্ট ( SEGFAULT ) হয়। এটি একটি বাগ, দুর্বলতা, কোডের সাথে মিশ্রিত ডেটা (আক্ষরিক পুলিং) বা ইচ্ছাকৃত মেমরি আত্মদর্শনের ফলে ঘটতে পারে।

ডিভাইস সমর্থন এবং প্রভাব

প্রয়োজনীয় প্যাচ ছাড়া আগের হার্ডওয়্যার বা আগের কার্নেল (4.9-এর কম) সহ ডিভাইসগুলি এই বৈশিষ্ট্যটি সম্পূর্ণরূপে সমর্থন বা উপকৃত নাও হতে পারে। কার্নেল সমর্থন ছাড়া ডিভাইসগুলি শুধুমাত্র এক্সিকিউট মেমরির ব্যবহারকারীর অ্যাক্সেসগুলি প্রয়োগ করতে পারে না, তবে কার্নেল কোড যা স্পষ্টভাবে পরীক্ষা করে যে একটি পৃষ্ঠা পাঠযোগ্য কিনা তা এখনও এই বৈশিষ্ট্যটি প্রয়োগ করতে পারে, যেমন process_vm_readv()

কার্নেলের ফ্ল্যাগ CONFIG_ARM64_UAO অবশ্যই কার্নেলে সেট করতে হবে যাতে কার্নেল শুধুমাত্র এক্সিকিউট হিসেবে চিহ্নিত ইউজারল্যান্ড পেজগুলোকে সম্মান করে। পূর্বের ARMv8 ডিভাইস, বা ARMv8.2 ডিভাইসের সাথে User Access Override (UAO) নিষ্ক্রিয় করা হয়েছে, তারা এর থেকে পুরোপুরি উপকৃত নাও হতে পারে এবং এখনও syscalls ব্যবহার করে শুধুমাত্র এক্সিকিউট পৃষ্ঠাগুলি পড়তে সক্ষম হতে পারে।

বিদ্যমান কোড রিফ্যাক্টরিং

AArch32 থেকে পোর্ট করা কোডে মিশ্র ডেটা এবং কোড থাকতে পারে, যার ফলে সমস্যা দেখা দিতে পারে। অনেক ক্ষেত্রে, এই সমস্যাগুলির সমাধান করা অ্যাসেম্বলি ফাইলের একটি .data বিভাগে ধ্রুবকগুলি সরানোর মতোই সহজ।

স্থানীয়ভাবে পুল করা ধ্রুবকগুলিকে আলাদা করার জন্য হাতে লেখা সমাবেশকে রিফ্যাক্টর করার প্রয়োজন হতে পারে।

উদাহরণ:

ক্ল্যাং কম্পাইলার দ্বারা উত্পন্ন বাইনারিগুলির কোডে ডেটা মিশ্রিত হওয়ার সাথে কোনও সমস্যা থাকা উচিত নয়। যদি GNU কম্পাইলার সংগ্রহ (GCC) জেনারেটেড কোড অন্তর্ভুক্ত করা হয় (একটি স্ট্যাটিক লাইব্রেরি থেকে), আউটপুট বাইনারি পরীক্ষা করে নিশ্চিত করুন যে কোড বিভাগে ধ্রুবকগুলি পুল করা হয়নি।

যদি এক্সিকিউটেবল কোড বিভাগে কোড আত্মদর্শন প্রয়োজন হয়, তাহলে কোডটি পঠনযোগ্য চিহ্নিত করতে প্রথমে mprotect কল করুন। তারপর অপারেশন সম্পূর্ণ হওয়ার পরে, অপঠনযোগ্য চিহ্নিত করতে আবার mprotect কল করুন।

সক্রিয় করা হচ্ছে

বিল্ড সিস্টেমের সমস্ত 64-বিট বাইনারিগুলির জন্য ডিফল্টরূপে শুধুমাত্র এক্সিকিউট সক্রিয় করা হয়।

নিষ্ক্রিয় করা হচ্ছে

আপনি শুধুমাত্র একটি মডিউল স্তরে, একটি সম্পূর্ণ সাবডিরেক্টরি ট্রি দ্বারা, অথবা একটি সম্পূর্ণ বিল্ডের জন্য বিশ্বব্যাপী নিষ্ক্রিয় করতে পারেন।

LOCAL_XOM এবং xom ভেরিয়েবলকে false সেট করে XOM পৃথক মডিউলগুলির জন্য নিষ্ক্রিয় করা যেতে পারে যেগুলিকে রিফ্যাক্টর করা যায় না বা তাদের এক্সিকিউটেবল কোড পড়তে হবে।

// Android.mk
LOCAL_XOM := false

// Android.bp
cc_binary { // or other module types
   ...
   xom: false,
}

যদি একটি স্ট্যাটিক লাইব্রেরিতে এক্সিকিউট-অনলি মেমরি নিষ্ক্রিয় করা থাকে, তবে বিল্ড সিস্টেমটি স্ট্যাটিক লাইব্রেরির সমস্ত নির্ভরশীল মডিউলগুলিতে এটি প্রয়োগ করে। আপনি xom: true, ব্যবহার করে এটিকে ওভাররাইড করতে পারেন।

একটি নির্দিষ্ট সাবডিরেক্টরিতে শুধুমাত্র এক্সিকিউট মেমরি নিষ্ক্রিয় করতে (উদাহরণস্বরূপ, foo/bar/), মানটি XOM_EXCLUDE_PATHS এ পাস করুন।

make -j XOM_EXCLUDE_PATHS=foo/bar

বিকল্পভাবে, আপনি আপনার পণ্য কনফিগারেশনে PRODUCT_XOM_EXCLUDE_PATHS ভেরিয়েবল সেট করতে পারেন৷

আপনি আপনার make কমান্ডে ENABLE_XOM=false পাস করে বিশ্বব্যাপী শুধুমাত্র এক্সিকিউট বাইনারি নিষ্ক্রিয় করতে পারেন।

make -j ENABLE_XOM=false

বৈধতা

শুধুমাত্র এক্সিকিউট মেমরির জন্য কোন CTS বা যাচাইকরণ পরীক্ষা নেই। আপনি readelf ব্যবহার করে এবং সেগমেন্ট ফ্ল্যাগ পরীক্ষা করে ম্যানুয়ালি বাইনারি যাচাই করতে পারেন।