init প্রসেসটির প্রায় অবাধ অনুমতি রয়েছে এবং এটি বুট প্রক্রিয়ার সময় সিস্টেমকে চালু করার জন্য সিস্টেম ও ভেন্ডর উভয় পার্টিশন থেকেই ইনপুট স্ক্রিপ্ট ব্যবহার করে। এই অ্যাক্সেসটি ট্রেবল-এর সিস্টেম/ভেন্ডর বিভাজনে একটি বিশাল ফাঁক তৈরি করে, কারণ ভেন্ডর স্ক্রিপ্টগুলো init-কে এমন সব ফাইল, প্রোপার্টি ইত্যাদি অ্যাক্সেস করার নির্দেশ দিতে পারে, যেগুলো স্থিতিশীল সিস্টেম-ভেন্ডর অ্যাপ্লিকেশন বাইনারি ইন্টারফেস (ABI)-এর অংশ নয়।
এই ফাঁকটি পূরণ করার জন্যই Vendor init-কে ডিজাইন করা হয়েছে। vendor_init একটি পৃথক, নিরাপত্তা-বর্ধিত লিনাক্স (SELinux) ডোমেইন ব্যবহার করে, যা /vendor এ থাকা কমান্ডগুলোকে বিক্রেতা-নির্দিষ্ট অনুমতিসহ চালায়।
প্রক্রিয়া
ভেন্ডর ইনিট, বুট প্রক্রিয়ার একেবারে শুরুতে u:r:vendor_init:s0 SELinux কনটেক্সট সহ init-এর একটি সাব-প্রসেস ফোর্ক করে। এই SELinux কনটেক্সটটির ডিফল্ট init কনটেক্সটের তুলনায় অনেক কম পারমিশন থাকে এবং এর অ্যাক্সেস সেইসব ফাইল, প্রোপার্টি ইত্যাদির মধ্যে সীমাবদ্ধ থাকে যা হয় ভেন্ডর-নির্দিষ্ট অথবা স্থিতিশীল সিস্টেম-ভেন্ডর ABI-এর অংশ।
Init লোড করার সময় প্রতিটি স্ক্রিপ্ট পরীক্ষা করে দেখে যে সেটির পাথ /vendor দিয়ে শুরু হয় কি না এবং যদি হয়, তবে সেটিকে একটি ট্যাগ দিয়ে চিহ্নিত করে দেয় যে এর কমান্ডগুলো অবশ্যই vendor init কনটেক্সটে চালাতে হবে। প্রতিটি init বিল্টইন-কে একটি বুলিয়ান দিয়ে টীকাযুক্ত করা হয়, যা নির্দিষ্ট করে দেয় যে কমান্ডটি vendor init সাবপ্রসেসে চালাতে হবে কি না।
- ফাইল সিস্টেম অ্যাক্সেস করে এমন বেশিরভাগ কমান্ড ভেন্ডর ইনিট সাবপ্রসেসে চালানোর জন্য টীকাযুক্ত থাকে এবং তাই সেগুলো ভেন্ডর ইনিট এসইপলিসির অধীন।
- বেশিরভাগ কমান্ড যা অভ্যন্তরীণ ইনিট অবস্থাকে প্রভাবিত করে (যেমন, সার্ভিস চালু ও বন্ধ করা) সেগুলো সাধারণ ইনিট প্রসেসের মধ্যেই চালানো হয়। এই কমান্ডগুলোকে জানানো হয় যে, একটি ভেন্ডর স্ক্রিপ্ট তাদের নিজস্ব নন-এসইলিনাক্স পারমিশন হ্যান্ডলিং করার জন্য তাদেরকে কল করছে।
init-এর প্রধান প্রসেসিং লুপে একটি চেক ব্যবস্থা রয়েছে, যার মাধ্যমে যাচাই করা হয় যে, যদি কোনো কমান্ড vendor সাবপ্রসেসে চালানোর জন্য অ্যানোটেট করা থাকে এবং সেটি কোনো vendor স্ক্রিপ্ট থেকে আসে, তবে সেই কমান্ডটি ইন্টার-প্রসেস কমিউনিকেশন (IPC)-এর মাধ্যমে vendor init সাবপ্রসেসে পাঠানো হয়। এই vendor init সাবপ্রসেসটি কমান্ডটি চালায় এবং ফলাফলটি আবার init-এ ফেরত পাঠায়।
ভেন্ডর ইনিট ব্যবহার করুন
ভেন্ডর ইনিট ডিফল্টরূপে সক্রিয় থাকে এবং এর সীমাবদ্ধতা /vendor পার্টিশনে উপস্থিত সমস্ত ইনিট স্ক্রিপ্টের ক্ষেত্রে প্রযোজ্য। যেসব ভেন্ডরের স্ক্রিপ্ট ইতোমধ্যেই শুধুমাত্র সিস্টেমের ফাইল, প্রোপার্টি ইত্যাদি অ্যাক্সেস করে না, তাদের কাছে ভেন্ডর ইনিট স্বচ্ছ হওয়া উচিত।
তবে, কোনো নির্দিষ্ট ভেন্ডর স্ক্রিপ্টের কমান্ডগুলো যদি ভেন্ডরের ইনিট বিধিনিষেধ লঙ্ঘন করে, তাহলে কমান্ডগুলো ব্যর্থ হয়। ব্যর্থ কমান্ডগুলোর জন্য কার্নেল লগে (যা dmesg দিয়ে দেখা যায়) ইনিট থেকে একটি লাইন থাকে, যা ব্যর্থতা নির্দেশ করে। SELinux পলিসির কারণে ব্যর্থ হওয়া যেকোনো কমান্ডের সাথে একটি SELinux অডিটও করা হয়। SELinux অডিটসহ একটি ব্যর্থতার উদাহরণ:
type=1400 audit(1511821362.996:9): avc: denied { search } for pid=540 comm="init" name="nfc" dev="sda45" ino=1310721 scontext=u:r:vendor_init:s0 tcontext=u:object_r:nfc_data_file:s0 tclass=dir permissive=0
init: Command 'write /data/nfc/bad_file_access 1234' action=boot (/vendor/etc/init/hw/init.walleye.rc:422) took 2ms and failed: Unable to write to file '/data/nfc/bad_file_access': open() failed: Permission deniedযদি কোনো কমান্ড ব্যর্থ হয়, তাহলে দুটি বিকল্প আছে:
- যদি কোনো উদ্দিষ্ট সীমাবদ্ধতার কারণে কমান্ডটি ব্যর্থ হয় (যেমন, যদি কমান্ডটি কোনো সিস্টেম ফাইল বা প্রপার্টি অ্যাক্সেস করে), তবে কমান্ডটিকে অবশ্যই শুধুমাত্র স্টেবল ইন্টারফেস ব্যবহার করে ট্রেবল-বান্ধব উপায়ে পুনরায় প্রয়োগ করতে হবে। নেভারঅ্যালাউ রুল এমন সিস্টেম ফাইল অ্যাক্সেস করার অনুমতি যোগ করা থেকে বিরত রাখে, যেগুলো স্টেবল সিস্টেম-ভেন্ডর ABI-এর অংশ নয়।
- যদি SELinux লেবেলটি নতুন হয় এবং সিস্টেমের
vendor_init.teতে এটিকে আগে থেকেই অনুমতি দেওয়া না থাকে অথবা neverallow নিয়মের মাধ্যমে অনুমতি বাদ দেওয়া না হয়, তাহলে নতুন লেবেলটিকে ডিভাইস-নির্দিষ্টvendor_init.teতে অনুমতি দেওয়া যেতে পারে।
অ্যান্ড্রয়েড ৯-এর আগে বাজারে আসা ডিভাইসগুলোর ক্ষেত্রে, ডিভাইস-নির্দিষ্ট vendor_init.te ফাইলে data_between_core_and_vendor_violators typeattribute যোগ করে neverallows নিয়মগুলো এড়িয়ে যাওয়া যেতে পারে।
কোড অবস্থান
ভেন্ডর ইনিট আইপিসি-র লজিকের সিংহভাগ system/core/init/subcontext.cpp ফাইলে রয়েছে।
কমান্ডের তালিকাটি system/core/init/builtins.cpp- এর BuiltinFunctionMap ক্লাসে রয়েছে এবং এতে এমন অ্যানোটেশন অন্তর্ভুক্ত আছে যা নির্দেশ করে যে কমান্ডটি ভেন্ডর ইনিট সাবপ্রসেসে চালাতে হবে কি না।
ভেন্ডর ইনিট-এর জন্য SEPolicy-টি system/sepolicy-এর মধ্যে থাকা প্রাইভেট ( system/sepolicy/private/vendor_init.te ) এবং পাবলিক ( system/sepolicy/public/vendor_init.te ) ডিরেক্টরিগুলোতে বিভক্ত।