چطور Semgrep تحلیل Taint رو ۷۵٪ سریعتر کرد
خلاصهٔ کاملتر
به گفتهٔ نویسنده، این نوشته دومین قسمت از یه سری سهقسمتی دربارهٔ بهتر کردن کارایی Semgrepه. Semgrep یه ابزار تحلیل استاتیک کده که با قواعد (rule) داخل کد دنبال الگوهای مشکلدار میگرده. قابلیت مهمش تحلیل Taintه: دنبال کردن مسیر دادهای که از یه ورودی کاربر (source) راه میافته و ممکنه به یه نقطهٔ خطرناک مثل eval (sink) برسه. هر قاعده چهار دسته الگو داره — source، propagator، sanitizer و sink — و موتور چک میکنه که آیا دادهی آلوده از منبع به مقصد میرسه یا نه.
از نسخهٔ Pro در ۲۰۲۳، Semgrep میتونست این مسیر رو بین چند فایل مختلف هم دنبال کنه (تحلیل interfile). نویسنده توضیح میده که برای این کار اول یه «محیط نامگذاری» میسازن تا بفهمن یه تابع تو یه فایل همون تابعیه که جای دیگه تعریف شده، بعد امضاهای taint رو حساب میکنن که نشون میده کدوم source ممکنه به کدوم sink برسه.
مشکل اصلی این بود که بهخاطر یه تصمیم قدیمی، موتور این تحلیل رو عملاً دو بار انجام میداد؛ اول بین فایلها و بعد دوباره داخل هر فایل. نویسنده به نقل از یکی از همتیمیهاش میگه اگه اون موقع چند هفتهٔ بیشتر وقت گذاشته بودن، میشد از همون اول taint رو فقط یه بار اجرا کرد.
تیم با پروفایلری که قبلاً برای OCaml ساخته بودن (Pyro Caml) اندازه گرفتن که این کار چقدر گرونه. طبق دادهها، تو یه بازهٔ ۵۳ روزهٔ زمان CPU، حدود ۱۸ روزش صرف پاس اول taint میشد که تازه موازی هم نبود. نویسنده تأکید میکنه که این زمان CPUه نه زمان واقعی، ولی همین یکسوم از کل هزینه رو توجیه میکرد که برن سراغ اصلاحش.
نویسنده میگه دلیل اینکه زودتر این کارو نکردن، نبودِ یه راهحل خوب برای موازیسازی قبل از OCaml 5.0 بود. قبلش برای موازیسازی باید پروسه رو fork میکردن که مصرف حافظه رو چند برابر میکرد و برای نگهداشتن اینهمه taint config تو حافظه جواب نمیداد. با اومدن مالتیکور تو OCaml 5، اجرای یهبارهٔ taint عملی شد.
مرحلهٔ سخت، تستها بود: بعد از بازنویسی، بیش از ۲۰۰ تست شکست خورد که تیم زبانبهزبان رفت سراغشون. بعد Semgrep رو روی دهها ریپوی محکخورده اجرا کردن (حدود ۲۵٪ سرعت بیشتر) و در آخر یه آزمایش A/B واقعی روی ۱٪ اسکنهای کاربرها بهصورت shadow انجام دادن تا مطمئن شن نتایج امنیتی خراب نمیشه. یه فلگ هم برای برگشت به رفتار قبلی گذاشتن.
نتیجه به گفتهٔ نویسنده چشمگیر بود: صدک ۹۵ زمان اسکن از ۱۰ دقیقه به ۷ دقیقه و نیم و صدک ۹۹ از ~۴۵ دقیقهٔ پرنوسان به ۳۵ دقیقهٔ پایدارتر رسید. برای دو ریپوی بزرگ کاربرهای مهم، زمان از ۹ ساعت به ۵ ساعت و ۲۰ دقیقه و از ۳ ساعت و ۲۰ دقیقه به ۵۰ دقیقه اومد پایین.
نکات کلیدی:
- تحلیل Taint مسیر دادههای کاربر رو از source تا sink دنبال میکنه تا آسیبپذیری پیدا کنه
- موتور Semgrep این تحلیل رو دو بار انجام میداد و همین ~یکسوم زمان CPU رو میخورد
- پاس اول موازی نبود، پس اضافهکردن هسته هم کمکی نمیکرد
- مالتیکورِ OCaml 5 اجرای یهبارهٔ taint رو عملی کرد
- روی اسکنهای کامل تا ۷۵٪ سریعتر و برای بعضی ریپوها بیش از ۳ برابر بهبود دیده شد




