নিয়ন্ত্রণ প্রবাহ অখণ্ডতা

২০১৬ সালের হিসাব অনুযায়ী, অ্যান্ড্রয়েডের সকল দুর্বলতার প্রায় ৮৬% মেমোরি সুরক্ষা সম্পর্কিত। বেশিরভাগ দুর্বলতা আক্রমণকারীরা ব্যবহার করে অ্যাপের স্বাভাবিক নিয়ন্ত্রণ প্রবাহ পরিবর্তন করে অপব্যবহারকারী অ্যাপের সমস্ত সুবিধা ব্যবহার করে ইচ্ছামত ক্ষতিকারক কার্যকলাপ সম্পাদন করে। কন্ট্রোল ফ্লো ইন্টিগ্রিটি (CFI) হল একটি নিরাপত্তা ব্যবস্থা যা একটি সংকলিত বাইনারির মূল নিয়ন্ত্রণ প্রবাহ গ্রাফে পরিবর্তনগুলিকে অনুমোদন দেয় না, যার ফলে এই ধরনের আক্রমণ করা উল্লেখযোগ্যভাবে কঠিন হয়ে পড়ে।

অ্যান্ড্রয়েড ৮.১-এ, আমরা মিডিয়া স্ট্যাকে LLVM-এর CFI বাস্তবায়ন সক্ষম করেছি। অ্যান্ড্রয়েড ৯-এ, আমরা আরও উপাদান এবং কার্নেলেও CFI সক্ষম করেছি। সিস্টেম CFI ডিফল্টরূপে চালু থাকে তবে আপনাকে কার্নেল CFI সক্ষম করতে হবে।

LLVM-এর CFI-এর জন্য Link-Time Optimization (LTO) ব্যবহার করে কম্পাইলিং করা প্রয়োজন। LTO অবজেক্ট ফাইলের LLVM বিটকোড উপস্থাপনাকে লিঙ্ক-টাইম পর্যন্ত সংরক্ষণ করে, যা কম্পাইলারকে কী অপ্টিমাইজেশন করা যেতে পারে সে সম্পর্কে আরও ভালভাবে যুক্তি করতে দেয়। LTO সক্ষম করলে চূড়ান্ত বাইনারিটির আকার হ্রাস পায় এবং কর্মক্ষমতা উন্নত হয়, তবে কম্পাইলের সময় বৃদ্ধি পায়। অ্যান্ড্রয়েডে পরীক্ষায়, LTO এবং CFI-এর সংমিশ্রণের ফলে কোডের আকার এবং কর্মক্ষমতার উপর নগণ্য ওভারহেড হয়; কিছু ক্ষেত্রে উভয়েরই উন্নতি হয়।

CFI এবং অন্যান্য ফরোয়ার্ড-কন্ট্রোল চেকগুলি কীভাবে পরিচালনা করা হয় সে সম্পর্কে আরও প্রযুক্তিগত বিবরণের জন্য, LLVM ডিজাইন ডকুমেন্টেশন দেখুন।

উদাহরণ এবং উৎস

কম্পাইলার দ্বারা CFI সরবরাহ করা হয় এবং কম্পাইলের সময় বাইনারিতে ইন্সট্রুমেন্টেশন যোগ করা হয়। আমরা ক্ল্যাং টুলচেইনে CFI এবং AOSP-তে অ্যান্ড্রয়েড বিল্ড সিস্টেম সমর্থন করি।

/platform/build/target/product/cfi-common.mk এর কম্পোনেন্ট সেটের জন্য Arm64 ডিভাইসের জন্য CFI ডিফল্টরূপে সক্রিয় থাকে। এটি /platform/frameworks/av/media/libmedia/Android.bp এবং /platform/frameworks/av/cmds/stagefright/Android.mk এর মতো মিডিয়া কম্পোনেন্টের makefiles/blueprint ফাইলের একটি সেটেও সরাসরি সক্রিয় থাকে।

বাস্তবায়নকারী সিস্টেম সিএফআই

ক্ল্যাং এবং অ্যান্ড্রয়েড বিল্ড সিস্টেম ব্যবহার করলে CFI ডিফল্টরূপে সক্রিয় থাকে। যেহেতু CFI অ্যান্ড্রয়েড ব্যবহারকারীদের নিরাপদ রাখতে সাহায্য করে, তাই আপনার এটি অক্ষম করা উচিত নয়।

আসলে, আমরা আপনাকে অতিরিক্ত উপাদানগুলির জন্য CFI সক্ষম করার জন্য জোরালোভাবে উৎসাহিত করছি। আদর্শ প্রার্থীরা হলেন বিশেষাধিকারপ্রাপ্ত নেটিভ কোড, অথবা নেটিভ কোড যা অবিশ্বস্ত ব্যবহারকারীর ইনপুট প্রক্রিয়া করে। আপনি যদি ক্ল্যাং এবং অ্যান্ড্রয়েড বিল্ড সিস্টেম ব্যবহার করেন, তাহলে আপনি আপনার মেকফাইল বা ব্লুপ্রিন্ট ফাইলগুলিতে কয়েকটি লাইন যোগ করে নতুন উপাদানগুলিতে CFI সক্ষম করতে পারেন।

মেকফাইলে CFI সাপোর্ট করা হচ্ছে

/platform/frameworks/av/cmds/stagefright/Android.mk এর মতো একটি make ফাইলে CFI সক্রিয় করতে, যোগ করুন:

LOCAL_SANITIZE := cfi
# Optional features
LOCAL_SANITIZE_DIAG := cfi
LOCAL_SANITIZE_BLACKLIST := cfi_blacklist.txt
  • LOCAL_SANITIZE নির্মাণের সময় CFI কে স্যানিটাইজার হিসেবে নির্দিষ্ট করে।
  • LOCAL_SANITIZE_DIAG CFI-এর জন্য ডায়াগনস্টিক মোড চালু করে। ডায়াগনস্টিক মোড ক্র্যাশের সময় logcat-এ অতিরিক্ত ডিবাগ তথ্য প্রিন্ট করে, যা আপনার বিল্ডগুলি তৈরি এবং পরীক্ষা করার সময় কার্যকর। তবে, প্রোডাকশন বিল্ডগুলিতে ডায়াগনস্টিক মোডটি সরিয়ে ফেলতে ভুলবেন না।
  • LOCAL_SANITIZE_BLACKLIST উপাদানগুলিকে পৃথক ফাংশন বা উৎস ফাইলের জন্য CFI যন্ত্রাংশ নির্বাচনীভাবে অক্ষম করার অনুমতি দেয়। ব্যবহারকারীর মুখোমুখি হওয়া যেকোনো সমস্যা সমাধানের জন্য আপনি শেষ অবলম্বন হিসাবে একটি কালো তালিকা ব্যবহার করতে পারেন। আরও বিস্তারিত জানার জন্য, CFI নিষ্ক্রিয় করা দেখুন।

ব্লুপ্রিন্ট ফাইলগুলিতে CFI সমর্থন করা হচ্ছে

/platform/frameworks/av/media/libmedia/Android.bp এর মতো ব্লুপ্রিন্ট ফাইলে CFI সক্রিয় করতে, যোগ করুন:

   sanitize: {
        cfi: true,
        diag: {
            cfi: true,
        },
        blacklist: "cfi_blacklist.txt",
    },

সমস্যা সমাধান

যদি আপনি নতুন কম্পোনেন্টগুলিতে CFI সক্ষম করেন, তাহলে আপনি ফাংশন টাইপ মিসমেচ এরর এবং অ্যাসেম্বলি কোড টাইপ মিসমেচ এরর সহ কয়েকটি সমস্যার সম্মুখীন হতে পারেন।

ফাংশন টাইপের অমিল ত্রুটি ঘটে কারণ CFI পরোক্ষ কলগুলিকে শুধুমাত্র সেই ফাংশনগুলিতে যেতে বাধা দেয় যেগুলিতে কলে ব্যবহৃত স্ট্যাটিক টাইপের মতো একই গতিশীল টাইপ থাকে। CFI ভার্চুয়াল এবং নন-ভার্চুয়াল সদস্য ফাংশন কলগুলিকে কেবল সেই অবজেক্টগুলিতে যেতে বাধা দেয় যা কল করার জন্য ব্যবহৃত অবজেক্টের স্ট্যাটিক টাইপের একটি ডেরিভেটিভ ক্লাস। এর অর্থ, যখন আপনার কাছে এমন কোড থাকে যা এই অনুমানগুলির যেকোনো একটি লঙ্ঘন করে, তখন CFI যে ইন্সট্রুমেন্টেশন যোগ করে তা বাতিল হয়ে যাবে। উদাহরণস্বরূপ, স্ট্যাক ট্রেস একটি SIGABRT দেখায় এবং logcat একটি লাইন ধারণ করে যেখানে নিয়ন্ত্রণ প্রবাহ অখণ্ডতা একটি অমিল খুঁজে বের করার বিষয়ে উল্লেখ করা হয়।

এটি ঠিক করার জন্য, নিশ্চিত করুন যে কল করা ফাংশনটি স্ট্যাটিক্যালি ঘোষিত একই ধরণের। এখানে দুটি উদাহরণ CLs দেওয়া হল:

আরেকটি সম্ভাব্য সমস্যা হল এমন কোডে CFI সক্ষম করার চেষ্টা করা যা অ্যাসেম্বলিতে পরোক্ষ কল ধারণ করে। যেহেতু অ্যাসেম্বলি কোড টাইপ করা হয় না, এর ফলে টাইপের অমিল দেখা দেয়।

এটি ঠিক করার জন্য, প্রতিটি অ্যাসেম্বলি কলের জন্য নেটিভ কোড র‍্যাপার তৈরি করুন এবং র‍্যাপারগুলিকে কলিং পয়েন্টারের মতো একই ফাংশন সিগনেচার দিন। র‍্যাপারটি তখন সরাসরি অ্যাসেম্বলি কোড কল করতে পারে। যেহেতু ডাইরেক্ট ব্রাঞ্চগুলি CFI দ্বারা ইন্সট্রুমেন্ট করা হয় না (রানটাইমে এগুলি পুনরায় পয়েন্ট করা যায় না এবং তাই কোনও নিরাপত্তা ঝুঁকি তৈরি করে না), এটি সমস্যার সমাধান করবে।

যদি অনেকগুলি অ্যাসেম্বলি ফাংশন থাকে এবং সেগুলি সব ঠিক করা না যায়, তাহলে আপনি অ্যাসেম্বলিতে পরোক্ষ কল ধারণকারী সমস্ত ফাংশনকে কালো তালিকাভুক্ত করতে পারেন। এটি সুপারিশ করা হয় না কারণ এটি এই ফাংশনগুলিতে CFI চেকগুলি অক্ষম করে, যার ফলে আক্রমণ পৃষ্ঠ খোলা হয়।

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

আমরা কোনও পারফরম্যান্স ওভারহেড লক্ষ্য করিনি, তাই আপনার CFI নিষ্ক্রিয় করার প্রয়োজন নেই। তবে, যদি ব্যবহারকারী-মুখী কোনও প্রভাব থাকে, তাহলে আপনি কম্পাইলের সময় একটি স্যানিটাইজার ব্ল্যাকলিস্ট ফাইল সরবরাহ করে পৃথক ফাংশন বা সোর্স ফাইলের জন্য CFI নির্বাচনীভাবে অক্ষম করতে পারেন। ব্ল্যাকলিস্ট কম্পাইলারকে নির্দিষ্ট স্থানে CFI ইন্সট্রুমেন্টেশন নিষ্ক্রিয় করার নির্দেশ দেয়।

অ্যান্ড্রয়েড বিল্ড সিস্টেমটি মেক এবং সুং উভয়ের জন্যই প্রতি-কম্পোনেন্ট ব্ল্যাকলিস্টের জন্য সমর্থন প্রদান করে (যা আপনাকে সোর্স ফাইল বা পৃথক ফাংশন নির্বাচন করতে দেয় যা CFI ইন্সট্রুমেন্টেশন গ্রহণ করবে না)। ব্ল্যাকলিস্ট ফাইলের ফর্ম্যাট সম্পর্কে আরও তথ্যের জন্য, আপস্ট্রিম ক্ল্যাং ডক্স দেখুন।

বৈধতা

বর্তমানে, CFI-এর জন্য বিশেষভাবে কোনও CTS পরীক্ষা নেই। পরিবর্তে, নিশ্চিত করুন যে CFI ডিভাইসের উপর প্রভাব ফেলছে না তা যাচাই করার জন্য CTS পরীক্ষাগুলি CFI সক্ষম থাকা অবস্থায় বা ছাড়াই পাস করে।