
DR.CHECKER : Linux कर्नेल ड्राइवरों के लिए एक Soundy भेद्यता पहचान उपकरण

इस रेपो में सभी स्रोत, सेटअप स्क्रिप्ट शामिल हैं। अब संबंधित स्रोत फ़ाइलों के साथ चेतावनियों को देखने के लिए एक अद्भुत UI के साथ।
Ubuntu >= 14.04.5 LTS
16 फरवरी 2018:
पूर्व-निर्मित डॉकर कंटेनर में DR.CHECKER का उपयोग करने के विवरण के लिए Docker Usage दस्तावेज़ देखें।
हमारा कार्यान्वयन LLVM पर आधारित है, विशेष रूप से LLVM 3.8। हमें हेडर पार्स करने के लिए c2xml जैसे टूल की भी आवश्यकता है।
सबसे पहले, सुनिश्चित करें कि आपके पास cmake (setup/build स्क्रिप्ट द्वारा उपयोग किया जाता है) और libxml (c2xml के लिए आवश्यक) है:
sudo apt-get install cmake libxml2-dev
इसके बाद, हमने एक एकल स्क्रिप्ट बनाई है, जो सभी आवश्यक टूल को डाउनलोड और बिल्ड करती है।
cd helper_scripts
python setup_drchecker.py --help
usage: setup_drchecker.py [-h] [-b TARGET_BRANCH] [-o OUTPUT_FOLDER]
optional arguments:
-h, --help show this help message and exit
-b TARGET_BRANCH Branch (i.e. version) of the LLVM to setup. Default:
release_38 e.g., release_38
-o OUTPUT_FOLDER Folder where everything needs to be setup.
उदाहरण:
python setup_drchecker.py -o drchecker_deps
सेटअप पूरा करने के लिए आपको अपने स्थानीय PATH पर्यावरण चर में संशोधन की भी आवश्यकता है। सेटअप स्क्रिप्ट आपको बताएगी कि आपको कौन से परिवर्तन करने हैं।
यह Setup के सफल समापन पर निर्भर करता है। हमारे पास एक एकल स्क्रिप्ट है जो सब कुछ बिल्ड करती है, आपका स्वागत है।
cd llvm_analysis
./build.sh
यह Build के सफल समापन पर निर्भर करता है। DR.CHECKER को कर्नेल ड्राइवरों पर चलाने के लिए, हमें पहले उन्हें llvm बिटकोड में बदलना होगा।
पहले, हमारे पास एक बिल्ड करने योग्य कर्नेल होना चाहिए। इसका मतलब है कि आप नियमित बिल्ड सेटअप का उपयोग करके कर्नेल को संकलित करने में सक्षम होना चाहिए। यानी make।
हम पहले make कमांड के आउटपुट को कैप्चर करते हैं, इस आउटपुट से हम सटीक संकलन कमांड निकालते हैं।
make (या makeout.txt) का आउटपुट उत्पन्न करनाबस V=1 पास करें और आउटपुट को फ़ाइल में रीडायरेक्ट करें।
उदाहरण:
make V=1 O=out ARCH=arm64 > makeout.txt 2>&1
नोट: कई प्रक्रियाओं का उपयोग न करें यानी -j। मल्टी-प्रोसेसिंग मोड में चलाने से आउटपुट फ़ाइल खराब हो जाएगी क्योंकि कई प्रक्रियाएँ आउटपुट फ़ाइल में लिखने का प्रयास करती हैं।
बस इतना ही। DR.CHECKER यहाँ से देखभाल करेगा।
DR.CHECKER विश्लेषण चलाने के लिए कई चरण हैं, ये सभी चरण एक एकल स्क्रिप्ट helper_scripts/runner_scripts/run_all.py में लिपटे हुए हैं।
कैसे चलाएं:
python run_all.py --help
usage: run_all.py [-h] [-l LLVM_BC_OUT] [-a CHIPSET_NUM] [-m MAKEOUT] [-g COMPILER_NAME] [-n ARCH_NUM] [-o OUT] [-k KERNEL_SRC_DIR] [-skb] [-skl] [-skp] [-ske] [-ski] [-f SOUNDY_ANALYSIS_OUT]
optional arguments:
-h, --help show this help message and exit
-l LLVM_BC_OUT Destination directory where all the generated bitcode files should be stored.
-a CHIPSET_NUM Chipset number. Valid chipset numbers are:
1(mediatek)|2(qualcomm)|3(huawei)|4(samsung)
-m MAKEOUT Path to the makeout.txt file.
-g COMPILER_NAME Name of the compiler used in the makeout.txt, This is
needed to filter out compilation commands. Ex: aarch64-linux-android-gcc
-n ARCH_NUM Destination architecture, 32 bit (1) or 64 bit (2).
-o OUT Path to the out folder. This is the folder, which
could be used as output directory during compiling
some kernels. (Note: Not all kernels needs a separate out folder)
-k KERNEL_SRC_DIR Base directory of the kernel sources.
-skb Skip LLVM Build (default: not skipped).
-skl Skip Dr Linker (default: not skipped).
-skp Skip Parsing Headers (default: not skipped).
-ske Skip Entry point identification (default: not
skipped).
-ski Skip Soundy Analysis (default: not skipped).
-f SOUNDY_ANALYSIS_OUT Path to the output folder where the soundy analysis output should be stored.
स्क्रिप्ट सभी ड्राइवरों पर DR.CHECKER को बिल्ड, लिंक और चलाती है, इसलिए इसमें काफी समय (45 मिनट-90 मिनट) लग सकता है। यदि आप DR.CHECKER को व्यक्तिगत ड्राइवरों पर मैन्युअल रूप से चलाना चाहते हैं, तो standalone देखें।
उपरोक्त स्क्रिप्ट सभी CPU कोर का उपयोग करने के लिए मल्टीप्रोसेसर मोड में निम्नलिखित कार्य करती है:
उत्पन्न सभी बिटकोड फ़ाइलें -l तर्क को दिए गए फ़ोल्डर में रखी जाएँगी।
यह चरण आपके पास मौजूद कोर की संख्या के आधार पर काफी समय लेता है।
इसलिए, यदि आपने पहले ही यह चरण कर लिया है, तो आप -skb पास करके इस चरण को छोड़ सकते हैं।
यह लिंकिंग करता है, यह सभी बिटकोड फ़ाइलों से गुज़रता है और संबंधित बिटकोड फ़ाइलों की पहचान करता है जिन्हें लिंक करने की आवश्यकता है और उन्हें (llvm-link का उपयोग करके) एक समेकित बिटकोड फ़ाइल में लिंक करता है (जो संबंधित बिटकोड फ़ाइल के साथ संग्रहीत की जाएगी)।
उपरोक्त चरण के समान, आप -skl पास करके इस चरण को छोड़ सकते हैं।
यह चरण हेडर फ़ाइलों में एंट्री पॉइंट घोषणाओं की तलाश करता है और उनके कॉन्फ़िगरेशन को फ़ाइल में संग्रहीत करता है: LLVM बिल्ड निर्देशिका के अंतर्गत hdr_file_config.txt।
छोड़ने के लिए: -skp
यह चरण सभी ड्राइवर समेकित बिटकोड फ़ाइलों में सभी एंट्री पॉइंट की पहचान करता है।
आउटपुट LLVM बिल्ड निर्देशिका के अंतर्गत फ़ाइल: entry_point_out.txt में संग्रहीत किया जाएगा।
फ़ाइल entry_point_out.txt की सामग्री का उदाहरण:
FileRead:hidraw_read:/home/drchecker/33.2.A.3.123/llvm_bc_out/drivers/hid/llvm_link_final/final_to_check.bc
FileWrite:hidraw_write:/home/drchecker/33.2.A.3.123/llvm_bc_out/drivers/hid/llvm_link_final/final_to_check.bc
IOCTL:hidraw_ioctl:/home/drchecker/33.2.A.3.123/llvm_bc_out/drivers/hid/llvm_link_final/final_to_check.bc
छोड़ने के लिए: -ske
यह चरण फ़ाइल entry_point_out.txt में सभी एंट्री पॉइंट पर DR.CHECKER चलाएगा। प्रत्येक एंट्री पॉइंट के लिए आउटपुट विकल्प -f के लिए प्रदान किए गए फ़ोल्डर में संग्रहीत किया जाएगा।
छोड़ने के लिए: -ski
अब, हम एक उदाहरण दिखाएंगे जहाँ से आपके पास कर्नेल स्रोत हैं, भेद्यता चेतावनियाँ प्राप्त करने तक।
हमने एक mediatek कर्नेल 33.2.A.3.123.tar.bz2 अपलोड किया है। पहले उपरोक्त फ़ाइल को डाउनलोड और एक्सट्रैक्ट करें।
मान लें कि आपने उपरोक्त फ़ाइल को एक फ़ोल्डर में निकाला है जिसे कहा जाता है: ~/mediatek_kernel
cd ~/mediatek_kernel
source ./env.sh
cd kernel-3.18
# the following step may not be needed depending on the kernel
mkdir out
make O=out ARCH=arm64 tubads_defconfig
# this following command copies all the compilation commands to makeout.txt
make V=1 -j8 O=out ARCH=arm64 > makeout.txt 2>&1
cd <repo_path>/helper_scripts/runner_scripts
python run_all.py -l ~/mediatek_kernel/llvm_bitcode_out -a 1 -m ~/mediatek_kernel/kernel-3.18/makeout.txt -g aarch64-linux-android-gcc -n 2 -o ~/mediatek_kernel/kernel-3.18/out -k ~/mediatek_kernel/kernel-3.18 -f ~/mediatek_kernel/dr_checker_out
उपरोक्त कमांड में काफी समय (30 मिनट - 1 घंटा) लगता है।
पहले, सभी विश्लेषण परिणाम फ़ोल्डर में होंगे: ~/mediatek_kernel/dr_checker_out (विकल्प -f को दिया गया तर्क), प्रत्येक एंट्री पॉइंट के लिए एक .json फ़ाइल बनाई जाएगी जिसमें सभी चेतावनियाँ JSON प्रारूप में होंगी। ये json फ़ाइलें संदर्भों द्वारा आयोजित चेतावनियाँ रखती हैं।
दूसरा, फ़ोल्डर ~/mediatek_kernel/dr_checker_out/instr_warnings (विकल्प -f के संबंध में) में निर्देश स्थान के अनुसार आयोजित चेतावनियाँ होती हैं।
इन चेतावनियों का विश्लेषण हमारे Visualizer का उपयोग करके किया जा सकता है।
अंत में, प्रत्येक एंट्री पॉइंट के लिए सभी चेतावनियों का एक सारांश, प्रकार के अनुसार आयोजित, आउटपुट CSV फ़ाइल:** ~/mediatek_kernel/dr_checker_out/warnings_stats.csv (विकल्प -f के संबंध में)** में लिखा जाएगा।
-g के लिए मानविकल्प -g के लिए मान प्रदान करने के लिए आपको कर्नेल को संकलित करने के लिए उपयोग किए जाने वाले *-gcc बाइनरी का नाम जानना होगा।
यह जानने का एक आसान तरीका makeout.txt में gcc के लिए grep करना होगा और आप संकलक कमांड देखेंगे जिससे आप *-gcc बाइनरी नाम जान सकते हैं।
हमारे उपरोक्त उदाहरण के लिए, यदि आप उदाहरण बिल्ड के लिए grep gcc makeout.txt करते हैं, तो आपको नीचे जैसी कई पंक्तियाँ दिखाई देंगी:
aarch64-linux-android-gcc -Wp,-MD,fs/jbd2/.transaction.o.d -nostdinc -isystem ...
इसलिए, -g का मान aarch64-linux-android-gcc होना चाहिए।
यदि बनाया जाने वाला कर्नेल 32-बिट है, तो बाइनरी सबसे अधिक arm-eabi-gcc होगी।
-a के लिए मानचिपसेट प्रकार पर निर्भर करते हुए, आपको संबंधित संख्या प्रदान करनी होगी।
-o के लिए मानयह कर्नेल बिल्ड के दौरान make कमांड के लिए विकल्प O= को प्रदान किए गए फ़ोल्डर का पथ है।
सभी कर्नेल को एक अलग आउट पथ की आवश्यकता नहीं होती है। आप विकल्प O प्रदान किए बिना कर्नेल बना सकते हैं, ऐसी स्थिति में आपको run_all.py चलाते समय उस विकल्प के लिए मान प्रदान नहीं करना चाहिए।
हम सभी चेतावनियों को देखने के लिए एक वेब-आधारित UI प्रदान करते हैं। कृपया Visualization देखें।
आप BugDetectorDriver.cpp में संबंधित #define DISABLE_* पंक्तियों को अनकम्मेंट करके एक या अधिक भेद्यता जाँचकर्ताओं को अक्षम कर सकते हैं।
आपकी पसंद के अनुसार, हम परिणामों को पोस्ट-प्रोसेस करने के लिए एक स्क्रिप्ट भी प्रदान करते हैं। इसे देखें।
मज़े करें!!