SELinux যাচাই করা হচ্ছে

অ্যান্ড্রয়েড দৃঢ়ভাবে OEM-কে তাদের SELinux বাস্তবায়নকে পুঙ্খানুপুঙ্খভাবে পরীক্ষা করার জন্য উৎসাহিত করে। যেহেতু নির্মাতারা SELinux প্রয়োগ করে, তাদের প্রথমে ডিভাইসের পরীক্ষামূলক পুলে নতুন নীতি প্রয়োগ করা উচিত।

একটি নতুন নীতি প্রয়োগ করার পরে, getenforce কমান্ড জারি করে নিশ্চিত করুন যে SELinux ডিভাইসে সঠিক মোডে চলছে।

এটি গ্লোবাল SELinux মোড প্রিন্ট করে: হয় এনফোর্সিং অথবা পারমিসিভ। প্রতিটি ডোমেনের জন্য SELinux মোড নির্ধারণ করতে, আপনাকে অবশ্যই সংশ্লিষ্ট ফাইলগুলি পরীক্ষা করতে হবে বা /platform/system/sepolicy/tools/ এ উপস্থিত উপযুক্ত ( -p ) পতাকা সহ sepolicy-analyze এর সর্বশেষ সংস্করণটি চালাতে হবে।

অস্বীকৃতি পড়া

ত্রুটিগুলি পরীক্ষা করুন, যা ইভেন্ট লগ হিসাবে dmesg এবং logcat এ রাউট করা হয় এবং ডিভাইসে স্থানীয়ভাবে দেখা যায়৷ নির্মাতাদের এই ডিভাইসগুলিতে dmesg জন্য SELinux আউটপুট পরীক্ষা করা উচিত এবং অনুমতিমূলক মোডে সর্বজনীন প্রকাশের আগে সেটিংস পরিমার্জন করা উচিত এবং শেষ পর্যন্ত এনফোর্সিং মোডে স্যুইচ করা উচিত। SELinux লগ বার্তাগুলিতে avc: এবং তাই সহজেই grep এর সাথে পাওয়া যেতে পারে। cat /proc/kmsg চালানোর মাধ্যমে চলমান অস্বীকার লগগুলি ক্যাপচার করা বা cat /sys/fs/pstore/console-ramoops চালিয়ে পূর্ববর্তী বুট থেকে অস্বীকার লগগুলি ক্যাপচার করা সম্ভব।

SELinux ত্রুটি বার্তাগুলি বুট সম্পূর্ণ হওয়ার পরে লগগুলিকে জলাবদ্ধতা এড়াতে রেট-সীমিত। আপনি সমস্ত প্রাসঙ্গিক বার্তা দেখতে পাচ্ছেন তা নিশ্চিত করতে আপনি adb shell auditctl -r 0 চালিয়ে এটি নিষ্ক্রিয় করতে পারেন।

এই আউটপুট দিয়ে, নির্মাতারা সহজেই সনাক্ত করতে পারে যখন সিস্টেম ব্যবহারকারী বা উপাদানগুলি SELinux নীতি লঙ্ঘন করছে। সফ্টওয়্যার, SELinux নীতি বা উভয় পরিবর্তনের মাধ্যমে, নির্মাতারা তখন এই খারাপ আচরণটি মেরামত করতে পারে।

বিশেষত, এই লগ বার্তাগুলি নির্দেশ করে যে কোন প্রক্রিয়াগুলি এনফোর্সিং মোডের অধীনে ব্যর্থ হবে এবং কেন৷ এখানে একটি উদাহরণ:

avc: denied  { connectto } for  pid=2671 comm="ping" path="/dev/socket/dnsproxyd"
scontext=u:r:shell:s0 tcontext=u:r:netd:s0 tclass=unix_stream_socket

এই আউটপুটটিকে এভাবে ব্যাখ্যা করুন:

  • উপরের { connectto } টি গৃহীত পদক্ষেপের প্রতিনিধিত্ব করে৷ শেষে tclass এর সাথে একসাথে ( unix_stream_socket ), এটি আপনাকে মোটামুটি বলে যে কি করা হচ্ছে। এই ক্ষেত্রে, কিছু একটি ইউনিক্স স্ট্রিম সকেটের সাথে সংযোগ করার চেষ্টা করছিল।
  • scontext (u:r:shell:s0) আপনাকে বলে যে কোন প্রেক্ষাপট ক্রিয়াটি শুরু করেছে। এই ক্ষেত্রে এই শেল হিসাবে চলমান কিছু.
  • tcontext (u:r:netd:s0) আপনাকে অ্যাকশনের টার্গেটের প্রসঙ্গ বলে। এই ক্ষেত্রে, এটি একটি ইউনিক্স_স্ট্রিম_সকেট যা netd এর মালিকানাধীন।
  • শীর্ষে comm="ping" আপনাকে একটি অতিরিক্ত ইঙ্গিত দেয় যে অস্বীকার করার সময় কী চালানো হয়েছিল। এই ক্ষেত্রে, এটি একটি চমত্কার ভাল ইঙ্গিত.

আরেকটি উদাহরণ:

adb shell su root dmesg | grep 'avc: '

আউটপুট:

<5> type=1400 audit: avc:  denied  { read write } for  pid=177
comm="rmt_storage" name="mem" dev="tmpfs" ino=6004 scontext=u:r:rmt:s0
tcontext=u:object_r:kmem_device:s0 tclass=chr_file

এই অস্বীকারের মূল উপাদানগুলি এখানে রয়েছে:

  • অ্যাকশন - চেষ্টা করা অ্যাকশনটি বন্ধনীতে হাইলাইট করা হয়, read write বা setenforce
  • অভিনেতা - scontext (উৎস প্রসঙ্গ) এন্ট্রি অভিনেতার প্রতিনিধিত্ব করে, এই ক্ষেত্রে rmt_storage ডেমন।
  • অবজেক্ট - tcontext (টার্গেট কনটেক্সট) এন্ট্রি যে বস্তুর উপর কাজ করা হচ্ছে তার প্রতিনিধিত্ব করে, এই ক্ষেত্রে kmem।
  • ফলাফল - tclass (টার্গেট ক্লাস) এন্ট্রি নির্দেশ করে যে কোন ধরনের বস্তুর উপর কাজ করা হচ্ছে, এই ক্ষেত্রে একটি chr_file (ক্যারেক্টার ডিভাইস)।

ডাম্পিং ব্যবহারকারী এবং কার্নেল স্ট্যাক

কিছু ক্ষেত্রে, ইভেন্ট লগে থাকা তথ্য অস্বীকারের উত্স চিহ্নিত করার জন্য যথেষ্ট নয়। কেন অস্বীকৃতি ঘটেছে তা আরও ভালভাবে বোঝার জন্য কার্নেল এবং ইউজারস্পেস সহ কল ​​চেইন সংগ্রহ করা প্রায়শই কার্যকর।

সাম্প্রতিক কার্নেল avc:selinux_audited নামে একটি ট্রেসপয়েন্ট সংজ্ঞায়িত করে। এই ট্রেসপয়েন্ট সক্ষম করতে এবং কলচেন ক্যাপচার করতে Android simpleperf ব্যবহার করুন।

সমর্থিত কনফিগারেশন

  • লিনাক্স কার্নেল >= 5.10, বিশেষ করে অ্যান্ড্রয়েড কমন কার্নেল শাখা প্রধান লাইন এবং android12-5.10 সমর্থিত। android12-5.4 শাখাটিও সমর্থিত। আপনার ডিভাইসে ট্রেসপয়েন্ট সংজ্ঞায়িত করা হয়েছে কিনা তা নির্ধারণ করতে আপনি simpleperf ব্যবহার করতে পারেন: adb root && adb shell simpleperf list | grep avc:selinux_audited . অন্যান্য কার্নেল সংস্করণের জন্য, আপনি চেরি পিক কমিট dd81662 এবং 30969bc করতে পারেন।
  • আপনি যে ইভেন্টটি ডিবাগ করছেন সেটি পুনরুত্পাদন করা সম্ভব হওয়া উচিত। বুট টাইম ইভেন্ট simpleperf ব্যবহার করে সমর্থিত নয়; তবে আপনি এখনও ইভেন্টটি ট্রিগার করতে পরিষেবাটি পুনরায় চালু করতে সক্ষম হতে পারেন৷

কল চেইন ক্যাপচার করা

প্রথম ধাপ হল simpleperf record ব্যবহার করে ইভেন্ট রেকর্ড করা:

adb shell -t "cd /data/local/tmp && su root simpleperf record -a -g -e avc:selinux_audited"

অতঃপর, যে ঘটনাটি অস্বীকারের কারণ হয়েছিল তা শুরু করা উচিত। এর পরে, রেকর্ডিং বন্ধ করা উচিত। এই উদাহরণে, Ctrl-c ব্যবহার করে, নমুনাটি ক্যাপচার করা উচিত ছিল:

^Csimpleperf I cmd_record.cpp:751] Samples recorded: 1. Samples lost: 0.

অবশেষে, simpleperf report ক্যাপচার করা স্ট্যাকট্রেস পরিদর্শন করতে ব্যবহার করা যেতে পারে। এই ক্ষেত্রে:

adb shell -t "cd /data/local/tmp && su root simpleperf report -g --full-callgraph"
[...]
Children  Self     Command  Pid   Tid   Shared Object                                   Symbol
100.00%   0.00%    dmesg    3318  3318  /apex/com.android.runtime/lib64/bionic/libc.so  __libc_init
       |
       -- __libc_init
          |
           -- main
              toybox_main
              toy_exec_which
              dmesg_main
              klogctl
              entry_SYSCALL_64_after_hwframe
              do_syscall_64
              __x64_sys_syslog
              do_syslog
              selinux_syslog
              slow_avc_audit
              common_lsm_audit
              avc_audit_post_callback
              avc_audit_post_callback

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

পারমিসিভে স্যুইচ করা হচ্ছে

SELinux এনফোর্সমেন্ট ADB এর মাধ্যমে userdebug বা eng বিল্ডে নিষ্ক্রিয় করা যেতে পারে। এটি করার জন্য, প্রথমে adb root চালিয়ে রুটে ADB স্যুইচ করুন। তারপর, SELinux এনফোর্সমেন্ট অক্ষম করতে, চালান:

adb shell setenforce 0

অথবা কার্নেল কমান্ড লাইনে (প্রাথমিক ডিভাইস আনার সময়):

androidboot.selinux=permissive
androidboot.selinux=enforcing

অথবা অ্যান্ড্রয়েড 12 এ বুট কনফিগারেশনের মাধ্যমে:

androidboot.selinux=permissive
androidboot.selinux=enforcing

audit2allow ব্যবহার করে

audit2allow টুলটি dmesg অস্বীকৃতি গ্রহণ করে এবং সেগুলিকে সংশ্লিষ্ট SELinux নীতি বিবৃতিতে রূপান্তর করে। যেমন, এটি SELinux বিকাশকে ব্যাপকভাবে গতি দিতে পারে।

এটি ব্যবহার করতে, চালান:

adb pull /sys/fs/selinux/policy
adb logcat -b events -d | audit2allow -p policy

তা সত্ত্বেও, অনুমতির অত্যধিক পৌঁছানোর জন্য প্রতিটি সম্ভাব্য সংযোজন পরীক্ষা করার জন্য যত্ন নেওয়া আবশ্যক। উদাহরণস্বরূপ, নিম্নলিখিত প্রস্তাবিত SELinux নীতি বিবৃতিতে পূর্বের ফলাফল দেখানো rmt_storage অস্বীকারকে ফিডিং audit2allow দেয়:

#============= shell ==============
allow shell kernel:security setenforce;
#============= rmt ==============
allow rmt kmem_device:chr_file { read write };

এটি rmt কার্নেল মেমরি লেখার ক্ষমতা প্রদান করবে, একটি উজ্জ্বল নিরাপত্তা গর্ত। প্রায়শই audit2allow বিবৃতি শুধুমাত্র একটি সূচনা বিন্দু। এই বিবৃতিগুলি ব্যবহার করার পরে, একটি ভাল নীতিতে পৌঁছানোর জন্য আপনাকে উত্স ডোমেন এবং লক্ষ্যের লেবেল পরিবর্তন করতে হবে, পাশাপাশি যথাযথ ম্যাক্রোগুলি অন্তর্ভুক্ত করতে হবে৷ কখনও কখনও অস্বীকৃতি পরীক্ষা করা হলে নীতিগত কোনো পরিবর্তন হবে না; বরং আপত্তিকর আবেদন পরিবর্তন করা উচিত।