HWASan ক্র্যাশ কীভাবে পড়তে হয়, সে সম্পর্কে তথ্যের জন্য ‘Understanding HWASan reports’ দেখুন!
হার্ডওয়্যার-সহায়তাযুক্ত অ্যাড্রেসস্যানিটাইজার (HWASan) হলো অ্যাড্রেসস্যানিটাইজারের মতোই একটি মেমরি ত্রুটি শনাক্তকরণ টুল। ASan-এর তুলনায় HWASan অনেক কম র্যাম ব্যবহার করে, যা এটিকে সম্পূর্ণ সিস্টেম স্যানিটাইজেশনের জন্য উপযুক্ত করে তোলে। HWASan শুধুমাত্র অ্যান্ড্রয়েড ১০ এবং তার পরবর্তী সংস্করণগুলোতে এবং শুধুমাত্র AArch64 হার্ডওয়্যারে উপলব্ধ।
যদিও HWASan প্রধানত C/C++ কোডের জন্য উপযোগী, এটি জাভা ইন্টারফেস বাস্তবায়নের জন্য ব্যবহৃত C/C++ কোডের ক্র্যাশ সৃষ্টিকারী জাভা কোড ডিবাগ করতেও সাহায্য করতে পারে। এটি সহায়ক কারণ এটি মেমরি ত্রুটি ঘটার সাথে সাথেই ধরে ফেলে এবং আপনাকে সরাসরি দায়ী কোডটির দিকে নির্দেশ করে।
ক্লাসিক ASan-এর তুলনায় HWASan-এ রয়েছে:
- Similar CPU overhead (~2x)
- অনুরূপ কোড আকারের ওভারহেড (৪০ – ৫০%)
- অনেক কম র্যাম ওভারহেড (১০% – ৩৫%)
HWASan, ASan-এর মতোই একই ধরনের বাগ শনাক্ত করে:
- স্ট্যাক এবং হিপ বাফার ওভারফ্লো/আন্ডারফ্লো
- বিনামূল্যে ব্যবহারের পর প্রচুর ব্যবহার।
- স্কোপের বাইরে স্ট্যাক ব্যবহার
- Double free/wild free
এছাড়াও, HWASan রিটার্নের পরে স্ট্যাকের ব্যবহার শনাক্ত করে।
HWASan (যা ASan-এর অনুরূপ) UBSan-এর সাথে সামঞ্জস্যপূর্ণ, এবং উভয়ই একটি টার্গেটে একই সময়ে সক্রিয় করা যায়।
বাস্তবায়নের বিবরণ এবং সীমাবদ্ধতা
HWASan মেমরি ট্যাগিং পদ্ধতির উপর ভিত্তি করে তৈরি, যেখানে পয়েন্টার এবং মেমরি অ্যাড্রেসের পরিসর উভয়ের সাথেই একটি ছোট র্যান্ডম ট্যাগ মান যুক্ত থাকে। একটি মেমরি অ্যাক্সেস বৈধ হওয়ার জন্য, পয়েন্টার এবং মেমরি ট্যাগ অবশ্যই মিলতে হবে। HWASan অ্যাড্রেসের সর্বোচ্চ বিটগুলিতে পয়েন্টার ট্যাগ সংরক্ষণ করার জন্য ARMv8-এর টপ বাইট ইগনোর (TBI) ফিচারের উপর নির্ভর করে, যাকে ভার্চুয়াল অ্যাড্রেস ট্যাগিংও বলা হয়।
আপনি Clang ডকুমেন্টেশন সাইটে HWASan-এর ডিজাইন সম্পর্কে আরও পড়তে পারেন।
এর নকশা অনুযায়ী, ওভারফ্লো শনাক্ত করার জন্য HWASan-এ ASan-এর মতো সীমিত আকারের রেডজোন বা ফ্রি করার পর ব্যবহার শনাক্ত করার জন্য ASan-এর মতো সীমিত ধারণক্ষমতার কোয়ারেন্টাইন নেই। এই কারণে, ওভারফ্লো যত বড়ই হোক বা মেমোরি ডিঅ্যালোকেট করতে যত সময়ই লাগুক না কেন, HWASan একটি বাগ শনাক্ত করতে পারে। এটি HWASan-কে ASan-এর চেয়ে একটি বড় সুবিধা দেয়।
যাইহোক, HWASan-এর সম্ভাব্য ট্যাগ মানের সংখ্যা সীমিত (256), যার মানে প্রোগ্রামটির একবার নির্বাহের সময় কোনও বাগ বাদ পড়ার সম্ভাবনা 0.4%।
প্রয়োজনীয়তা
সাধারণ অ্যান্ড্রয়েড কার্নেলের সাম্প্রতিক সংস্করণগুলো (৪.১৪+) স্বয়ংক্রিয়ভাবে HWASan সমর্থন করে। অ্যান্ড্রয়েড ১০-এর নির্দিষ্ট শাখাগুলোতে HWASan-এর সমর্থন নেই।
অ্যান্ড্রয়েড ১১ থেকে HWASan-এর জন্য ইউজারস্পেস সাপোর্ট পাওয়া যাচ্ছে।
আপনি যদি একটি ভিন্ন কার্নেল নিয়ে কাজ করেন, তাহলে HWASan-এর জন্য প্রয়োজন যে লিনাক্স কার্নেলটি সিস্টেম কল আর্গুমেন্টে ট্যাগড পয়েন্টার গ্রহণ করবে। এর জন্য সমর্থন নিম্নলিখিত আপস্ট্রিম প্যাচসেটগুলিতে বাস্তবায়ন করা হয়েছে:
- arm64 ট্যাগযুক্ত ঠিকানা ABI
- arm64: কার্নেলে পাঠানো ব্যবহারকারী পয়েন্টারগুলির ট্যাগ পরিবর্তন করা
- mm: brk()/mmap()/mremap() ফাংশনে ভার্চুয়াল অ্যাড্রেস অ্যালিয়াস তৈরি করা পরিহার করুন।
- arm64: কার্নেল থ্রেড থেকে কল করা access_ok() ফাংশনে ট্যাগ করা ঠিকানাগুলি যাচাই করুন
আপনি যদি একটি কাস্টম টুলচেইন ব্যবহার করে বিল্ড করেন, তাহলে নিশ্চিত করুন যে তাতে LLVM কমিট c336557f পর্যন্ত সবকিছু অন্তর্ভুক্ত আছে।
HWASan ব্যবহার করুন
HWASan ব্যবহার করে সম্পূর্ণ প্ল্যাটফর্মটি বিল্ড করতে নিম্নলিখিত কমান্ডগুলো ব্যবহার করুন:
lunch aosp_walleye-userdebug # (or any other product)export SANITIZE_TARGET=hwaddressm -j
সুবিধার জন্য, আপনি aosp_coral_hwasan- এর মতো একটি প্রোডাক্ট ডেফিনিশনে SANITIZE_TARGET সেটিংটি যোগ করতে পারেন।
যারা AddressSanitizer-এর সাথে পরিচিত, তাদের জন্য বিল্ডের অনেক জটিলতা দূর হয়ে গেছে:
- দুইবার make চালানোর প্রয়োজন নেই।
- ইনক্রিমেন্টাল বিল্ড কোনো কনফিগারেশন ছাড়াই কাজ করে।
- ইউজারডেটা ফ্ল্যাশ করার প্রয়োজন নেই।
AddressSanitizer-এর কিছু বিধিনিষেধও তুলে নেওয়া হয়েছে:
- স্ট্যাটিক এক্সিকিউটেবল সমর্থিত।
- libc ছাড়া অন্য যেকোনো টার্গেটের স্যানিটাইজেশন বাদ দিলেও চলে। ASan-এর মতো এখানে এমন কোনো বাধ্যবাধকতা নেই যে, যদি কোনো লাইব্রেরি স্যানিটাইজ করা হয়, তবে সেটিকে লিঙ্ক করা যেকোনো এক্সিকিউটেবলকেও স্যানিটাইজ করতে হবে।
একই (বা উচ্চতর) বিল্ড নম্বরের HWASan এবং সাধারণ ইমেজের মধ্যে অবাধে পরিবর্তন করা যায়। ডিভাইসটি ওয়াইপ করার প্রয়োজন নেই।
কোনো মডিউলের স্যানিটাইজেশন এড়িয়ে যেতে, LOCAL_NOSANITIZE := hwaddress (Android.mk) অথবা sanitize: { hwaddress: false } (Android.bp) ব্যবহার করুন।
স্বতন্ত্র লক্ষ্যবস্তু জীবাণুমুক্ত করুন
একটি সাধারণ (অ-স্যানিটাইজড) বিল্ডে প্রতিটি টার্গেটের জন্য HWASan সক্রিয় করা যেতে পারে, তবে শর্ত হলো libc.so ও স্যানিটাইজ করা থাকতে হবে। bionic/libc/Android.bp-এর "libc_defaults" এর sanitize ব্লকে hwaddress: true যোগ করুন। এরপর আপনি যে টার্গেটে কাজ করছেন, সেখানেও একই কাজ করুন।
উল্লেখ্য যে, libc স্যানিটাইজ করলে সিস্টেম-ব্যাপী হিপ মেমরি অ্যালোকেশনের ট্যাগিং সক্ষম হয়, সেইসাথে libc.so ভেতরের মেমরি অপারেশনগুলোর ট্যাগও পরীক্ষা করা যায়। এর ফলে এমন বাইনারিগুলোতেও বাগ ধরা পড়তে পারে যেখানে HWASan সক্রিয় করা হয়নি, যদি ত্রুটিপূর্ণ মেমরি অ্যাক্সেসটি libc.so এর মধ্যে ঘটে (যেমন, delete() দ্বারা মুছে ফেলা মিউটেক্সের উপর pthread_mutex_unlock() )।
সম্পূর্ণ প্ল্যাটফর্মটি HWASan ব্যবহার করে বিল্ড করা হলে কোনো বিল্ড ফাইল পরিবর্তন করার প্রয়োজন নেই।
আরও ভালো স্ট্যাক ট্রেস
প্রোগ্রামের প্রতিটি মেমরি অ্যালোকেশন এবং ডিঅ্যালোকেশন ইভেন্টের জন্য একটি স্ট্যাক ট্রেস রেকর্ড করতে HWASan একটি দ্রুত, ফ্রেম-পয়েন্টার-ভিত্তিক আনওয়াইন্ডার ব্যবহার করে। অ্যান্ড্রয়েড ডিফল্টরূপে AArch64 কোডে ফ্রেম পয়েন্টার সক্রিয় করে, তাই এটি বাস্তবে খুব ভালোভাবে কাজ করে। যদি আপনার ম্যানেজড কোডের মাধ্যমে আনওয়াইন্ড করার প্রয়োজন হয়, তাহলে প্রসেস এনভায়রনমেন্টে HWASAN_OPTIONS=fast_unwind_on_malloc=0 সেট করুন। মনে রাখবেন যে, ত্রুটিপূর্ণ মেমরি অ্যাক্সেসের স্ট্যাক ট্রেস ডিফল্টরূপে "ধীরগতির" আনওয়াইন্ডার ব্যবহার করে; এই সেটিংটি শুধুমাত্র অ্যালোকেশন এবং ডিঅ্যালোকেশন ট্রেসকে প্রভাবিত করে। লোডের উপর নির্ভর করে এই অপশনটি সিপিইউ-এর উপর খুব বেশি চাপ সৃষ্টি করতে পারে।
প্রতীকীকরণ
'HWASan রিপোর্ট বোঝা' অংশে প্রতীকীকরণ দেখুন।
অ্যাপে HWASan
AddressSanitizer-এর মতোই, HWASan জাভা কোডের গভীরে প্রবেশ করতে পারে না, কিন্তু এটি JNI লাইব্রেরির বাগ শনাক্ত করতে পারে। Android 14-এর আগে পর্যন্ত, HWASan-বিহীন ডিভাইসে HWASan অ্যাপ চালানো সমর্থিত ছিল না ।
HWASan ডিভাইসে, Make-এ SANITIZE_TARGET:=hwaddress অথবা কম্পাইলার ফ্ল্যাগে -fsanitize=hwaddress ব্যবহার করে অ্যাপের কোড বিল্ড করার মাধ্যমে HWASan দিয়ে অ্যাপগুলো পরীক্ষা করা যায়। HWASan নয় এমন ডিভাইসে (যেগুলোতে Android 14 বা তার নতুন সংস্করণ চলছে), LD_HWASAN=1 সেট করে একটি wrap.sh ফাইল যোগ করতে হবে। আরও বিস্তারিত জানতে অ্যাপ ডেভেলপার ডকুমেন্টেশন দেখুন।