1 पॉइंट द्वारा GN⁺ 2024-04-05 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • GCC 14 का -fanalyzer C code के कई execution paths को symbolic execution के जरिए follow करता है और runtime से पहले पकड़ना मुश्किल defects को compile time पर खोजने पर केंद्रित है
  • इस बार के सुधार infinite loop detection, buffer overflow visualization, C string tracking, और taint analysis को default रूप से enable करने में बंटे हैं, और diagnostics को ज्यादा समझने योग्य बनाने पर केंद्रित हैं
  • -Wanalyzer-out-of-bounds सिर्फ warning से आगे बढ़कर text diagrams के जरिए buffer और write location के संबंध को दिखाता है, और UTF-8 strings में किस character के बीच में overflow हो रहा है यह भी दिखाता है
  • नया null_terminated_string_arg(PARAM_IDX) attribute analyzer और code readers को बताता है कि API null-terminated string की अपेक्षा करता है, जिससे null-terminated न किए गए buffer को pass करने वाले paths बेहतर तरीके से सामने आते हैं
  • Taint analysis -fanalyzer चुनने पर default रूप से चालू होता है, जिससे attacker-controlled values का upper-bound check के बिना size, index, offset आदि में इस्तेमाल होने वाला flow आसानी से देखा जा सकता है

-fanalyzer किन समस्याओं को संभालता है

  • -fanalyzer GCC का static analysis pass है, जो C source code के कई execution paths को symbolic execution करके compile time पर defects खोजने की कोशिश करता है
  • GCC 14 के सुधारों को अप्रैल 2024 की official release से पहले व्यवस्थित किया गया था, और लेख लिखे जाने के समय GCC 14.1 release अप्रैल 2024 में अपेक्षित थी
  • GCC 14.0 prerelease पहले से Fedora 40 Beta में इस्तेमाल हो रही है
  • Examples को Compiler Explorer पर नए compiler options के साथ आजमाया जा सकता है

सरल infinite loop detection

  • GCC 14 में नई warning -Wanalyzer-infinite-loop जोड़ी गई है
  • Example code में nested for statements में दूसरे loop की condition j < n है, लेकिन increment expression i++ ही रह गया है
    • यह पहले for statement को copy करने के बाद increment expression में i को j में न बदलने की गलती है
    • Analyzer इस path में j < n की true branch को लगातार follow करते हुए loop repetition की warning देता है
  • मौजूदा diagnostic output में flow समझने के लिए event numbers (1) से (5) तक क्रम से पढ़ना आसान है
  • GCC 15 में control flow path को highlight करने वाली ASCII art जैसी विधि से readability बढ़ाने का विचार अभी इच्छा-सूची में है
  • इस code को Compiler Explorer example में run किया जा सकता है

Buffer overflow को text में visualize करना

  • GCC 13 में analyzer ने -Wanalyzer-out-of-bounds के जरिए bounds checking support करना शुरू किया
  • GCC 14 में predicted buffer overflow के spatial relationship को text-based diagram के रूप में output किया जा सकता है
  • char buf[10] पर strcpy(buf, "hello") करने के बाद strcat(buf, " world!") call करने वाले example में stack-based buffer overflow detect होता है
    • पुराना message दिखाता था कि buf की capacity 10 bytes है और byte 10 से byte 12 तक out-of-bounds write होता है
    • GCC 14 का diagram strcpy द्वारा भरे गए destination buffer और strcat के start point बनने वाले मौजूदा terminating NUL byte को साथ में दिखाता है
  • Non-ASCII string example में भी UTF-8 representation को follow करते हुए overflow location दिखती है
    • char buf[11] में "サツキ" copy करने के बाद "メイ" append करने वाला code example के रूप में इस्तेमाल हुआ है
    • Diagram दिखाता है कि overflow character, यानी U+30E1 के बीच में होता है
  • संबंधित code ASCII string example और non-ASCII string example में देखा जा सकता है

C string operations की tracking बेहतर हुई

  • GCC 14 analyzer ने C string operations tracking को बेहतर किया है, और null terminator byte खोजते हुए buffer scan करने वाली APIs को simulate करता है
  • अगर pointer null-terminated न किए गए buffer को point करता है और उसे ऐसी API में pass करने वाला path है, तो warning देता है
  • नया function attribute null_terminated_string_arg(PARAM_IDX) analyzer और code readers को बताता है कि किसी specific parameter का null-terminated string होना जरूरी है
  • Example में example_fn(const char *p) पर null_terminated_string_arg(1) और nonnull attributes लगे हैं
    • char str[3] = "abc"; में null terminator byte रखने की जगह नहीं है
    • example_fn(str) call करते समय analyzer str के अंत के बाद 1 byte पढ़ने वाली stack-based buffer over-read की warning देता है
    • Diagnostic में यह note भी output होता है कि example_fn का पहला argument null-terminated string pointer होना चाहिए
  • इस example को Compiler Explorer पर run किया जा सकता है

Taint analysis default रूप से enabled

  • Analyzer का taint analysis attacker-controlled input, sanitization points, और बिना sanitization के इस्तेमाल होने वाली जगहों को track करता है
  • पिछले GCC releases में bugs और बहुत ज्यादा false positives के कारण यह default रूप से enabled नहीं था और अलग command-line argument के पीछे छिपा था
  • GCC 14 में कई bug fixes के बाद -fanalyzer चुनने पर taint analysis default रूप से चालू होता है
  • इस बदलाव से नीचे की 6 taint-based warnings भी साथ में activate होती हैं

CVE-2011-2210 से देखा गया kernel analysis case

  • Linux kernel के CVE-2011-2210 excerpt example को taint analysis case के रूप में इस्तेमाल किया गया है
  • __SYSCALL_DEFINEx macro में __attribute__((tainted_args)) जोड़कर analyzer को बताया जाता है कि osf_getsysinfo arguments trust boundary पार करके आए values हैं और उन्हें tainted values माना जाना चाहिए
  • GCC 14 analyzer copy_to_user(buffer, hwrpb, nbytes) में warning देता है कि attacker-controlled value nbytes को upper-bound check के बिना size के रूप में इस्तेमाल किया जा रहा है
    • Diagnostic दिखाता है कि nbytes पर if (nbytes < sizeof(*hwrpb)) में सिर्फ lower-bound check हुआ है
    • copy_to_user का तीसरा parameter access(write_only, 1, 3) attribute से size parameter के रूप में दिखाया जाता है
  • समस्या यह है कि sanitization condition if (nbytes < sizeof(*hwrpb)) के रूप में लिखी गई है
  • Kernel पर analyzer चलाकर vulnerabilities ढूंढने और analyzer false positives को ठीक करने का काम जारी है

1 टिप्पणियां

 
GN⁺ 2024-04-05
Hacker News की राय
  • मेरे लिए fanalyzer, Clang की तुलना में GCC की killer features में से एक है। यह errors समझा देता है, जिससे C programming बहुत आसान हो जाती है, और error messages भी developer-friendly होने के मामले में Rust जैसे लगने लगे हैं

    • मुझे पता है कि Rust, खासकर HN पर, memory safety और अच्छे abstractions के लिए बहुत ध्यान खींचता है, लेकिन सोचता हूं कि Rust की लोकप्रियता में error messages का कितना योगदान है
      technology सीखना छोड़ देने की सबसे बड़ी वजह अक्सर frustrate करने वाले या अस्पष्ट errors होते हैं। बात थोड़ी विषय से हट गई, लेकिन मतलब यह था कि मुझे C पसंद है और Rust-level error messages हों तो यह और बेहतर हो जाएगा
    • Clang में भी ऐसा ही tool है, Clang Static Analyzer: https://clang-analyzer.llvm.org/
    • मेरा अनुभव बिल्कुल उल्टा रहा। Clang अक्सर GCC से कहीं बेहतर error messages दिखाता है, कुछ warnings या errors की implementation ज्यादा cases पकड़ती है, और clang-tidy कहीं बेहतर static analysis देता है
    • याद आया कि C++ को इतना नापसंद करने की एक वजह यही थी। error: missing semicolon के बजाय template instantiation से जुड़े error messages की 1000 से ज्यादा lines बरस जाती थीं
    • यह बात काफी चौंकाने वाली लगती है। जानना चाहूंगा कि GCC analyzer ऐसा क्या अतिरिक्त पकड़ता है जिसे Clang static analyzer पहले से report नहीं करता
      मैंने GCC analyzer कुछ बार इस्तेमाल किया है, लेकिन output को पढ़ने लायक बनाने वाला कोई अच्छा frontend नहीं मिला। Clang में काफी अच्छा HTML output, CodeChecker, Xcode integration जैसे कई विकल्प हैं; सोचता हूं GCC-side output कैसे पढ़ते हैं। ऊपर से GCC, Clang की तुलना में false positives कहीं ज्यादा देता लगता है
  • दूसरे thread में 36 और comments हैं: https://news.ycombinator.com/item?id=39918278
    “GCC 14 Boasts Nice ASCII Art for Visualizing Buffer Overflows (phoronix.com)”, 2 घंटे पहले की post है

  • कुछ महीने पहले मैंने एक छोटा Linux utility बनाया था। यह किसी arbitrary executable की जगह लेने वाला drop-in shim था; call होने पर original program होने का नाटक करता, original को fork करता और stdout/stderr से जोड़ देता था
    error output उस program के context को जानने वाले custom GPT assistant को भेजा जाता था, और assistant original error को human-readable form में बदलकर shim के stderr पर निकालता था। GCC/Clang के concept/template से जुड़े nested compiler dumps देखने से तंग आकर इसका इस्तेमाल कर रहा था, लेकिन चाहें तो किसी भी program के साथ इस्तेमाल किया जा सकता था। यह ठीक काम करता था, लेकिन मैं बहुत बीमार हो गया और आगे काम नहीं कर पाया; कोई इसे फिर से ठीक से बनाए और generalize करे तो अच्छा project होगा

  • analysis results के लिए बेहतर output format हो तो अच्छा होगा। मौजूदा तरीका screen readers के लिए नरक है

    • संदर्भ के लिए, मैंने GCC 13 में SARIF output implement किया था, और उदाहरण के लिए VS Code में plugin से देखा जा सकता है। हालांकि इसमें ASCII art शामिल नहीं है
      output का example यहां देख सकते हैं: https://godbolt.org/z/aan6Kfxds
      article के पहले example में command-line option -fdiagnostics-format=sarif-stderr जोड़ा गया है। diagrams को SVG में output करने का experiment भी किया था, लेकिन GCC 14 में डालने लायक पर्याप्त polish नहीं कर पाया
  • original code ऐसा था कि nbytes < sizeof(*hwrpb) होने पर -1 return करता था, और copy_to_user(buffer, hwrpb, nbytes) fail होने पर -2 return करता था। लागू किया गया fix nbytes > sizeof(*hwrpb) check था, लेकिन मुझे लगता है सही fix copy_to_user(buffer, hwrpb, sizeof(*hwrpb)) है
    hwrpb pointer से sizeof(*hwrpb) के अलावा किसी और size को copy करना समझ में नहीं आता

    • अगर caller nbytes = 4 पास करे और sizeof(hwrpb) 16 bytes हो, तो caller buffer से 12 bytes ज्यादा copy करके उस memory को read किया जा सकता है जिसका वह मालिक नहीं है। मेरे हिसाब से इसे avoid करना चाहिए
      बेहतर solution यह है कि caller और callee दोनों जितने minimum bytes support करते हैं, उतने ही copy किए जाएं। जैसे nbytes = MIN(nbytes, sizeof(hwrpb));। यह मानते हुए कि hwrpb->size की version info maintained है, struct का कोई हिस्सा uninitialized होने पर भी backward/forward compatibility ensure की जा सकती है
    • सही। लेकिन buffer size दिया हुआ है तो caller buffer के end को overwrite करना भी समझ में नहीं आता, इसलिए nbytes से बड़ा value पास भी नहीं किया जा सकता
  • सच में शानदार। इसमें लगा काम बहुत बड़ा दिखता है। difficulty level standard library और C standard में fat pointer/array view introduce करने जैसा लगता है

  • -Wstringop-overflow में false positives इतने ज्यादा हैं कि यह सबसे पहले बंद की जाने वाली warning है। analyzer variant इससे बेहतर होगा, इसमें संदेह है

    • यह कुछ ऐसा नहीं है क्या जैसे carbon monoxide detector की battery निकाल देना, क्योंकि वह लगातार beep कर रहा है और उससे सिर दुखता है और नींद आती है
  • बहुत बढ़िया। आजकल मैं ज्यादा C development नहीं करता, इसलिए सोचता हूं strcpy और strcat कितनी बार इस्तेमाल होते हैं। आखिरी बार जब देखा था, तो ये goto जितनी ही taboo चीजों के करीब थे
    बेशक kernel development में goto को अक्सर prefer किया जाता है, यह पता है। सोचता हूं C string analysis असल में कितना मददगार है

    • कुछ contexts में goto का इस्तेमाल साफ तौर पर सही और elegant होता है। इसे हर हाल में avoid करने की कोशिश करने से maintain करना मुश्किल, बदसूरत और उलझा हुआ code बन सकता है। आम नहीं है, पर valid use cases हैं
      strcpy जैसे functions कम recommended हैं, लेकिन ऐसी situations भी होती हैं जहां stronger invariants, जैसे language-level invariants, न टूटें तो उनका सही होना guaranteed होता है। अगर ऐसा case टूट गया है तो पहले से ही कहीं बड़ा problem है। rare cases में यह argument भी किया जा सकता है कि nominally ज्यादा safe alternative बिना benefit के थोड़ा कम efficient हो सकता है
    • जब तक यह C में न मौजूद structured programming constructs के logically equivalent रूप में इस्तेमाल हो रहा है, goto के कुछ uses अब भी C में idiomatic हैं। सावधानी चाहिए, लेकिन आखिर C है, तो ऐसा हो सकता है
      हालांकि longjmp मुझे बिल्कुल पसंद नहीं है
    • simple goto use में कोई problem नहीं है। वहीं strxcpy family पूरी तरह mess है और किसी भी वजह से इस्तेमाल नहीं होनी चाहिए। kernel में इसका इस्तेमाल होना भयानक है
      ऐसे functions और उन्हें “ठीक करने” की सारी failed attempts को orbit से उड़ा देना चाहिए था
    • goto सावधानी से इस्तेमाल करें तो ठीक है। strcpy और strcat भी इस sense में “ठीक” हैं कि अगर आपको पता है code सही है और गलत हुआ तो बड़ा problem होगा। दुर्भाग्य से यह description C के बड़े हिस्से पर लागू होती है
    • मुझे नहीं लगता goto, strcat, strcpy जितना taboo है। goto ठीक है, और same scope में exact-size malloc के बिना इस्तेमाल होने वाले strcat और strcpy ज्यादा code smell जैसे हैं
  • बहुत अच्छा। क्या गलत हुआ, यह समझाने वाली detailed reports सभी के साथ लगी हैं, यह देखकर खुशी हुई