سی پلاس پلاس ایمن از نظر حافظه: ارائه TrapC به گروه کاری ISO C

دو هفته پیش، گروه کاری استانداردسازی بین‌المللی زبان برنامه‌نویسی C، پیشنهاد رابین رو، کارآفرین، برای TrapC، یک افزونه ایمن از نظر حافظه پیشگامانه برای زبان برنامه‌نویسی C را شنید.

رو در مصاحبه‌ای ایمیلی به TNS گفت: «بعد از ارائه من، به من گفتند که باید زمان بیشتری درخواست می‌کردم، اینکه 30 دقیقه کافی نبود. بنابراین بله، علاقه خوبی وجود دارد.»

افزونه رو با کد C موجود «بسیار سازگار» و حتی با C++ «تا حدودی سازگار» خواهد بود و راه دیگری را برای پایگاه کد عظیم جهان از کدهای ناایمن از نظر حافظه ارائه می‌دهد.

طبق مقاله سفید (whitepaper) ارائه شده توسط رو، هدف نهایی این است که «امکان تبدیل کد C قدیمی به فایل‌های اجرایی را فراهم کند که از نظر طراحی ایمن و به طور پیش‌فرض ایمن هستند» با کمترین بازسازی کد.

زبان‌های برنامه‌نویسی C و C++ در سال‌های اخیر به دلیل اینکه به توسعه‌دهندگان اجازه می‌دهند ناخواسته برنامه‌هایی با خطاهای حافظه بنویسند، تحت بررسی بوده‌اند، کد معیوبی که به کاربران مخرب اجازه می‌دهد بلوک حافظه را با کد شوم خود بازنویسی کنند. TrapC می‌تواند به این دسته از خطاها پایان دهد.

از مقاله رو.
از مقاله رو.

چگونه TrapC طراحی شده است

برای تحقق این امر، رو، ریاست Fountain Adobe، یک موسسه تحقیقاتی غیرانتفاعی در نزدیکی واشنگتن دی سی را بر عهده دارد. این موسسه در ماه نوامبر "برای حفظ مشخصات زبان TrapC و انتشار کامپایلر TrapC منبع باز رایگان" تاسیس شد و رو به من گفت که بودجه این سازمان غیرانتفاعی "برای بقیه سال تامین شده است"، اگرچه شرکت‌ها می‌توانند از توسعه مداوم حمایت کنند.

رو در ایمیل خود تأیید کرد که در حال حاضر یک کامپایلر وجود دارد که فایل‌های اجرایی x86، x64 یا ARM را از کد C استاندارد تولید می‌کند و آنها اکنون در حال کار بر روی پشتیبانی از افزونه‌های زبان اضافی برای TrapC هستند. (آنها کلمه کلیدی trap را برای ارائه مدیریت خطای ایمن به طور پیش‌فرض و alias را برای بارگذاری آسان عملگر و نوع اضافه می‌کنند، در حالی که از ویژگی‌های ایمنی کد C++ مانند سازنده‌ها، مخرب‌ها، new و توابع عضو استفاده مجدد می‌کنند.)

TrapC دو کلمه کلیدی C را حذف می‌کند: goto و union، که آن را "ناایمن و به طور گسترده از استفاده منسوخ شده" توصیف می‌کند. (بعداً مقاله سفید توصیه می‌کند که کد C با استفاده از آن کلمات کلیدی می‌تواند در یک کتابخانه کد C نگهداری شود و سپس توسط یک پروژه TrapC به آن پیوند داده شود...) اما هیجان فزاینده‌ای در مورد وعده و پتانسیل زبان آینده وجود دارد...

تصویر صفحه از پروفایل GitHub رابین رو

Register نوشت: «ممکن است برنامه‌نویسان C و C++ برای شرکت در تلاش برای ایمنی حافظه، نیازی به یادگیری Rust نداشته باشند.»

تصویر صفحه از یک نظر از انجمن TrapC Reddit

ایمنی با عملکرد

رو روز شنبه به من گفت که TrapC "در مسیر انتشار در سال 2025 قرار دارد". و او قول داد که "وقتی به اندازه کافی برای نمایش وجود داشته باشد، آن را به صورت آنلاین منتشر خواهیم کرد - بنابراین هر کسی می‌تواند TrapC را امتحان کند."

این یک پروژه بلندپروازانه است. رو هدف TrapC را چیزی کمتر از "ایمن کردن نرم‌افزار C/C++ در سطح زبان، کامپایل نرم‌افزاری که نمی‌تواند توسط رفتار غیرمنتظره مورد سوء استفاده قرار گیرد و هرگز خراب نمی‌شود" توصیف کرده است.

اما تکنیک‌های خاصی برای تحقق آن وجود دارد.

به گفته Register، رو در جلسه هیئت استاندارد ISO C گفت: «وقتی کد C با استفاده از کامپایلر TrapC کامپایل می‌شود، همه اشاره‌گرها به اشاره‌گرهای ایمن حافظه تبدیل می‌شوند و بررسی می‌شوند.» در TrapC، کامپایلر تعیین می‌کند که کدام اشاره‌گرها می‌توانند از محدوده خارج شوند - و آنها را روی صفر تنظیم می‌کند.

به گفته مقاله سفید، یکی از نتایج این امر این است که اشاره‌گرهای TrapC "همیشه به حافظه معتبر اشاره می‌کنند" و "نمی‌توانند از حد تجاوز کنند یا حاوی زباله باشند". از آنجایی که TrapC اندازه بافر را می‌داند (و تماشا می‌کند)، می‌داند چه زمانی کد نادرست "سعی می‌کند به حافظه نامعتبر فراتر از پایان‌دهنده تهی دست بزند."

اما آیا این می‌تواند بهبود عملکرد را نیز به همراه داشته باشد؟ رو به من می‌گوید: «برخلاف کامپایلر C، کامپایلر TrapC اطلاعات کاملی در مورد مناطق حافظه‌ای که اشاره‌گرهایش نگه می‌دارند، دارد» - به این معنی که می‌تواند بهتر بهینه‌سازی کند. کامپایلر TrapC به جای بررسی تک تک دسترسی‌های اشاره‌گر، می‌تواند با استفاده از استدلال کد هوش مصنوعی از بیشتر بررسی‌های مرزی اشاره‌گر ایمن حافظه اجتناب کند.

این امر او را به یک ادعای تحریک‌آمیز سوق می‌دهد. رو به من می‌گوید: «کارشناسان انتظار دارند که ایمنی حافظه گران باشد، اما آیا این لزوماً درست است؟» رو به من می‌گوید که در نهایت کد کامپایل TrapC می‌تواند هم کوچک‌تر و هم سریع‌تر باشد - به این معنی که هنگام محاسبه هزینه‌های عملکرد، ایمنی حافظه TrapC "ممکن است بهتر از رایگان باشد..."

بهبود عملکرد ممکن است از ویژگی‌های زبان TrapC دیگر نیز ناشی شود. به عنوان مثال، برخی از زبان‌های برنامه‌نویسی دارای کلمه کلیدی try هستند که اگر تلاش ناموفق باشد، یک خطا ایجاد می‌کند و منجر به یک شاخه کد برای آن استثنا می‌شود. اما مقاله سفید خاطرنشان می‌کند که "با TrapC، به نقل از یودا از جنگ ستارگان، "تلاشی وجود ندارد، فقط انجام دادن یا انجام ندادن وجود دارد.""

 int main()
  {
    gets_input();
    trap { puts("ERROR: invalid input");
          return 1;
         } return 0;
  }
 

بازگشت از یک فراخوانی تابع بدون خطا فقط از بلوک کد trap مدیریت خطا رد می‌شود. این مقاله اذعان می‌کند که این یک نحو جدید است که در C یا C++ یافت نمی‌شود.

بنابراین برخلاف C، TrapC به سرریز بافر (و سایر خطاها) با خاتمه دادن با یک پیام خطای مفید پاسخ می‌دهد.

و در حالی که این شبیه به یک تغییر جزئی است، رو به من می‌گوید که مکانیسم مدیریت خطای "trap" TrapC "از نظر زمان و فضا بهتر از هر مکانیسم مدیریت خطای موجود در C یا با استثنائات C++ است."

بهبود ایمنی بیشتر

مقاله سفید رو شامل مثالی از کدی است که معمولاً باعث خطای سرریز بافر می‌شود، اما در TrapC به جای آن برنامه را "با یک پیام خطای مفید" خاتمه می‌دهد.

 inline
 void gets_input()
            { char buffer[24];
                   printf("Please enter your name and press <ENTER>\n");
                   gets(buffer);// TrapC will terminate on overrun!
                   printf("%s", buffer);
            }
 

اما همین امر برای هر شرایط خطای غیرمنتظره دیگری نیز صادق خواهد بود، این مقاله اضافه می‌کند (از جمله، به عنوان مثال، خطاهای تقسیم بر صفر) - مگر اینکه برنامه‌نویس به صراحت کنترل‌کننده خطای trapping خود را ایجاد کند.

مقاله سفید همچنین به چندین ویژگی ایمنی TrapC دیگر اشاره می‌کند:

  • برای جلوگیری از خطاهای رایج، TrapC مدیریت حافظه خودکار را که در بسیاری از زبان‌های مدرن یافت می‌شود، ارائه می‌دهد.
  • در حالی که C همچنین می‌تواند با پیوست کردن به یک رشته، باعث سرریز بافر شود، "رشته‌های TrapC گسترش می‌یابند".
  • TypeC بررسی نوع خودکار را در دستورات printf هنگام استفاده از مشخص‌کننده "{}" ارائه می‌دهد، به عنوان مثال printf("{}",var);.
  • "TrapC printf() و scanf() از نظر نوع ایمن هستند، قابل بارگذاری هستند و از JSON و بومی‌سازی پشتیبانی داخلی دارند."
  • TrapC همچنین دارای توابع "wrapper" برای سایر توابع استاندارد C POSIX library است.
  • زبان برنامه‌نویسی C شامل کلمه کلیدی free() برای تخصیص حافظه است - ایجاد یک خطای احتمالی اگر یک اشاره‌گر سپس به آن مکان دسترسی پیدا کند. اما از آنجایی که مدیریت حافظه TrapC به طور خودکار اتفاق می‌افتد، این هرگز یک مشکل نیست، این مقاله توضیح می‌دهد. بنابراین "برای سازگاری C، اشکالی ندارد که در TrapC free() را فراخوانی کنید، اما نادیده گرفته می‌شود."
 int main()
{ int* p = malloc(sizeof(int));
  free(p);//TrapC ignores free, p not freed yet
  *p = 10;//UB in C, no problem in TrapC
  return 0;//Leaving Scope, TrapC now frees p automatically
}
 
  • TrapC "دارای یک نوع داده ممیز ثابت "decimal" مبتنی بر عدد صحیح است که برای استفاده در معاملات مالی مناسب است"
  • این مقاله سفید اضافه می‌کند که در آینده TrapC حتی ممکن است سعی کند ویژگی‌های ایمنی رشته را برای کمک به جلوگیری از شرایط مسابقه اضافه کند.

به طور خلاصه، TrapC "یک زبان برنامه‌نویسی منشعب شده از C است، با تغییراتی برای ایمن‌سازی LangSec و حافظه"، این مقاله نتیجه می‌گیرد. "برای انجام این کار، TrapC به دنبال حذف تمام رفتارهای تعریف نشده در زبان برنامه‌نویسی C است..."

یک IDE مجهز به هوش مصنوعی؟

در مارس 2024، رو همچنین یک استارت‌آپ انتفاعی به نام TRASEC تأسیس کرد که بر روی فناوری برنامه‌نویسی هوش مصنوعی مولد کار می‌کند.

رو به TNS گفت: «تاکنون بودجه از دوستان و خانواده تامین شده است» و افزود که او «در حال گفتگو با VCها است.»

TRASEC به توسعه کامپایلر TrapC کمک می‌کند، اما این فقط آغاز کار است. این مقاله سفید می‌گوید که این استارت‌آپ همچنین امیدوار است که در نهایت یک کامپایلر ویژه امنیت سایبری trapc با استدلال کد هوش مصنوعی منتشر کند - و این کار را در سال 2025 انجام دهد.

همانطور که رو به Register گفت، "برنامه تجاری این است که کامپایلر را به عنوان منبع باز رایگان ارائه دهیم و یک IDE هوش مصنوعی داشته باشیم که محصول پولی ما باشد."

رو در حالی که در ژانویه به سوالات در ساب‌ردیت "کارآفرینان" Reddit پاسخ می‌داد، گفت: «هدف نهایی او این است که هوش مصنوعی نرم‌افزاری ایجاد کند که غیرقابل هک و غیرقابل خراب شدن باشد.»

رو به من می‌گوید: «در دنیای بیرون، هوش مصنوعی مولد در نوشتن کد پایتون پیشرفت‌های زیادی می‌کند»، اما هنوز در نوشتن کد C "خیلی خوب" نیست. اما اگر کد تولید شده توسط هوش مصنوعی آنقدر خوب سازماندهی شده باشد که از برنامه‌نویسی "مدولار" به طور کامل پشتیبانی کند، با تمام عملکردهای فردی یک برنامه که به طور مرتب در فایل‌های جداگانه پنهان شده‌اند. رو پیشنهاد می‌کند که حتی ممکن است تست‌های واحد تولید شده خودکار وجود داشته باشد: "کد مدولار با تست‌های واحد، نه کد اسپاگتی."

بنابراین برخلاف C، TrapC به سرریز بافر (و سایر خطاها) با خاتمه دادن با یک پیام خطای مفید پاسخ می‌دهد.

او روی آن هم کار می‌کند. مقاله سفید رو خاطرنشان می‌کند که C در حال حاضر یک سیستم ساخت استاندارد به عنوان بخشی از خود زبان ندارد (مانند زنجیره ابزار Cargo Rust). بنابراین با نگاهی به آینده، "برای TrapC حیاتی است که یک زنجیره ابزار قابل حمل و آسان برای استفاده مانند Rust داشته باشد، بنابراین برنامه‌نویسان می‌توانند به سرعت و به راحتی سیستم‌های ساختی ایجاد کنند که در سراسر سیستم عامل‌ها کار می‌کنند."

خوشبختانه، رو در حال حاضر یک زنجیره ابزار برای تولید فایل‌های ساخت cmake دارد که برای پروژه نرم‌افزار گرافیکی طولانی مدت (و منبع باز) خود CinePaint ایجاد کرده است. رو شاخه منبع باز برنامه دستکاری تصویر گنو (یا GIMP) را رهبری کرد و به من می‌گوید که "نگهدارندگان GIMP دلیل خود را برای رها کردن شاخه هالیوود GIMP، که بعداً به CinePaint تغییر نام داد، به این دلیل دادند که بسیار پر از اشکال بود. منصفانه است که بگوییم مشکل حذف اشکالات حافظه در CinePaint، که به زبان C نوشته شده است، تجربه و انگیزه ایجاد TrapC را به من داد."

و همچنین او را با یک زنجیره ابزار سفارشی ساخته شده رها کرده است که نه تنها کد فایل‌های cmake را تولید می‌کند، بلکه کد boilerplate را برای کلاس‌ها، کد برنامه و حتی تست‌های واحد نیز تولید می‌کند. (و مقاله رو خاطرنشان می‌کند که حتی می‌تواند "به طور بأثر در پروژه‌های موجود که ممکن است فاقد سیستم ساخت باشند، استفاده شود.")

به گفته این مقاله، "Cmaker در حال حاضر از C++ پشتیبانی می‌کند"، اما "پشتیبانی از C و TrapC در راه است."

نمودار مقایسه C و Trapc

سازگاری و عملکرد

یک اسلاید در ارائه رو اذعان کرد که TrapC مینیمالیسم C را "حفظ می‌کند" - به این معنی که نسخه C++ از قالب‌ها، استثناها، بارگذاری بیش از حد تابع، وراثت یا چندشکلی را ارائه نمی‌دهد.

رو در مصاحبه ایمیلی ما توضیح داد: "سازگاری C و عملکرد بالا چیزی است که برنامه‌نویسان C به من می‌گویند که برای یک زبان ایمن حافظه برای جایگزینی قابل قبول کاملاً ضروری است." "صرف نظر کردن از ایمنی حافظه در C یک مصالحه طراحی بود که در دهه 1970 انجام شد. این یک انتخاب طراحی دشوار بین عملکرد، فراگیری و ایمنی بود - دو مورد را انتخاب کنید. ماموریت TrapC من این است که هر سه را انتخاب کنم.

"با C بسیار سازگار باشید و ایمنی حافظه داشته باشید که در مقایسه با مدیریت دستی حافظه در C هیچ هزینه‌ای نداشته باشد."

صرف نظر از کاستی‌هایش، یک اسلاید نهایی در ارائه رو به طور قاطع بیان می‌کند که TrapC "اشاره‌گرهای C/C++، scanf، printf و malloc را ایمن می‌کند."

و شامل چیزی است که به نظر می‌رسد بیانیه ماموریت برای TrapC است. "سخت کردن کد قدیمی: کد C/C++ معمولی را به برنامه‌هایی کامپایل کنید که نمی‌توانند بافر را سرریز کنند، نمی‌توانند خراب شوند."