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

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

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

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

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

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

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

/platform/build/target/product/cfi-common.mk এ উপাদানগুলির সেটের জন্য Arm64 ডিভাইসের জন্য ডিফল্টরূপে CFI সক্রিয় থাকে। এটি সরাসরি মিডিয়া উপাদানগুলির মেকফাইলস/ব্লুপ্রিন্ট ফাইলগুলির একটি সেটে সক্রিয় করা হয়েছে, যেমন /platform/frameworks/av/media/libmedia/Android.bp এবং /platform/frameworks/av/cmds/stagefright/Android.mk

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

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

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

মেকফাইলে CFI সমর্থন করা

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

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

ব্লুপ্রিন্ট ফাইলে CFI সমর্থন করে

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

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

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

আপনি যদি নতুন উপাদানগুলিতে CFI সক্ষম করে থাকেন তবে আপনি ফাংশন টাইপ অমিল ত্রুটি এবং সমাবেশ কোড টাইপ অমিল ত্রুটির সাথে কয়েকটি সমস্যায় পড়তে পারেন৷

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

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

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

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

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

CFI অক্ষম করা হচ্ছে

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

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

বৈধতা

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