فا

‫ برنامه نويسي امن با زبان C – عبارات و اعداد صحيح

IRCAR201007068
عنصر اصلي در كدنويسي امن با زبان هاي مختلف برنامه نويسي، مستند سازي خوب و استفاده از استانداردهاي قابل اجرا است. استانداردهاي كدنويسي، برنامه نويسان را ترغيب به پيروي از مجموعه اي متحدالشكل از قوانين و راهنماييها مي كند كه بر اساس نيازمندي هاي پروژه و سازمان تعيين شده است، نه بر اساس سلايق و مهارت هاي مختلف برنامه نويسان. به محض تعيين استانداردهاي مذكور، مي توان از آن به عنوان معياري براي ارزيابي كدهاي منبع، چه به صورت دستي و چه به صورت اتوماتيك استفاده كرد. از استانداردهاي معروف در اين زمينه مي توان به استانداردCERT براي كدنويسي امن اشاره كرد كه يك سري از قوانين و پيشنهادات را براي كد نويسي امن با زبان هاي برنامه نويسي C، C++ و جاوا ارائه مي دهد. هدف از اين قوانين و پيشنهادات، حذف عادت هاي كدنويسي ناامن و رفتارهاي تعريف نشده است كه منجر به آسيب پذيري هاي قابل سوءاستفاده مي شود. به كارگيري استانداردهاي مذكور منجر به توليد سيستم هاي با كيفيت بالاتر مي شود كه در برابر حملات بالقوه، پايدارتر و مقاوم تر هستند. در مقاله "آشنايي با استاندارد CERT براي برنامه نويسي امن"، كليات استاندارد CERT در زمينه مزبور را توضيح داديم و در اين مقاله به صورت تخصصي تر شيوه برنامه نويسي امن با زبان C را مورد بررسي قرار مي دهيم. قابل ذكر است كه در اين استاندارد 89 قانون و 134 پيشنهاد براي برنامه نويسي امن با زبان C ارائه شده است كه در سري مقالات كدنويسي امن با زبان C، مهمترين آنها را كه در سطح يك قرار دارند، شرح خواهيم داد. براي كسب اطلاعات بيشتر در مورد سطح بندي قوانين و پيشنهادات به مقاله "آشنايي با استاندارد CERT براي برنامه نويسي امن" مراجعه فرماييد.

عبارات يا Expressions)EXP)

پيشنهاد EXP01-C : از طول اشاره گر براي تعيين كردن طول نوعي كه به آن اشاره مي كند، استفاده نكنيد
از طول اشاره گر براي تعيين كردن طول نوعي كه به آن اشاره مي كند، استفاده نكنيد. دقت كنيد كه گرفتن طول "اشاره گر به يك نوع خاص"، همواره طول اشاره گر را بر مي گرداند و نه طول نوعي را كه به آن اشاره مي كند. اين مسئله در زمان محاسبه طول آرايه ها بسيار مشكل ساز مي شود. براي مثال كد زير به اشتباه از طول اشاره گر به جاي طول آرايه استفاده مي كند:



كد مذكور به صورت زير تصحيح مي شود:



قانون EXP33-C: قبل از مقدار دهي اوليه از متغيرها استفاده نكنيد
قبل از مقدار دهي اوليه از متغيرها استفاده نكنيد، زيرا حاوي مقادير پيش بيني نشده است. با وجود اينكه متغيرهاي مقداردهي نشده اغلب حاوي بيت هاي صفر مي باشند، ولي اين امر تضمين شده نيست و ممكن است متغيرهاي مقدار دهي نشده، حاوي آخرين مقدار ثبت شده در پشته برنامه باشند. به علاوه توابع حافظه مانند malloc() نبايد قبل از مقداردهي اوليه شدن مورد استفاده قرار گيرند، زيرا محتويات آنها نيز نامشخص است. در بسياري از موارد، كامپايلرها در مورد موارد استفاده نادرست از حافظه هشدار مي دهند. لازم است به هشدارهاي مذكور با دقت توجه شده و آنها را برطرف ساخت.

قانون EXP34-C: به اشاره گرهاي تهي ارجاع مجدد ندهيد
تلاش براي ارجاع مجدد به اشاره گرهاي تهي منجر به رفتارهاي تعريف نشده اي همچون خروج غير منتظره از برنامه مي شود. براي مثال در كد برنامه زير input_str در يك متغير رشته اي به نام str كه به صورت پويا مقداردهي شده است، كپي مي شود. در صورتي كه تابع malloc() به درستي اجرا نشود يك اشاره گر تهي يا null را برگردانده و به str اختصاص مي دهد. زماني كه به str در memcpy() ارجاع مجدد مي شود، برنامه به شكل غير منتظره اي رفتار مي كند.



براي برطرف ساختن مشكل مذكور تنها كافي است با يك دستور IF از تهي نبودن اشاره گر اطمينان حاصل كرد:


اعداد صحيح يا Integers)INT)

قانون INT34-C: يك عدد منفي و يا مقداري بيش از بيت هاي موجود در عملوند را شيفت ندهيد
اين قانون تأكيد مي كند كه نبايد يك عدد منفي و يا مقداري بيش از حد بيت هاي موجود در عملوند، بيت ها را شيفت داد. هر تلاشي براي اين كار منجر به خطاي منطقي مي شود و دقت كنيد كه اين خطا متفاوت از خطاي سرريز بافر است. شيفت دو طرفه داراي شيفت چپ با فرمت shift-expression<< additive-expression و شيفت راست با فرمت shift-expression<< additive-expression است. جابجايي بيت ها به اندازه عدد صحيح تعيين شده در عملگر، بر روي عملوند كه آن نيز داراي فرمت عدد صحيح (integer) است، انجام مي شود. براي مثال E1 << E2، E1 را به اندازه E2 شيفت چپ مي دهد. بيت هاي خالي شده با صفر پر مي شوند. در صورتي كه E1 عدد علامت دار نباشد و يا علامت دار بوده و مقدار غير منفي داشته باشد و همچنين E1 * 2E2 قابل نمايش در تعداد بيت هاي E1 باشد، E1، بيت به بيت به ميزان E2 مطابق شكل زير شيفت پيدا مي كند. در غير اين صورت رفتار عملگر مذكور غير قابل پيش بيني خواهد بود.



براي رهايي از نتايج غير منتظره در برنامه به جاي نوشتن



مي توان با استفاده از دستور IF به شكل زير برنامه را اصلاح كرد:



براي شيفت راست، در صورتي كه داشته باشيم E1 >> E2، اين دستور E1 را به اندازه E2 شيفت راست مي دهد. در صورتي كه E1 عدد علامت دار نباشد و يا علامت دار بوده و مقدار غير منفي داشته باشد، نتيجه قسمت صحيح معادله E1 / 2E2 خواهد بود. در صورتي كه E1 علامت دار بوده و مقدار منفي داشته باشد، رفتار عملگر نامشخص بوده و ممكن است شيفت رياضي علامت دار و يا شيفت منطقي بدون علامت انجام شود.



در شيفت راست نيز مي توان با استفاده از دستور IF، يك كد امن ايجاد كرد و از بروز نتايج نامشخص جلوگيري به عمل آورد:



قانون INT35-C: عبارت هاي عدد صحيح را در هنگام مقايسه كردن و نسبت دادن به يك اندازه بزرگتر ارزيابي كنيد
در صورتي كه يك عبارت عدد صحيح با يك عدد صحيح با اندازه بزرگتر مقايسه شود و يا به متغير عدد صحيح با اندازه بزرگتر نسبت داده شود، بايد به صورت صريح با استفاده از دستورات تبديل انواع (Casting) در اندازه بزرگتر مورد ارزيابي قرار گيرد. در قسمت بعدي به بررسي قوانين و پيشنهادات سطح يك در اعداد اعشاري و آرايه ها خواهيم پرداخت.

نظرات

بدون نظر
شما برای نظر دادن باید وارد شوید

نوشته

 
تاریخ ایجاد: 18 مرداد 1393

دسته‌ها

امتیاز

امتیاز شما
تعداد امتیازها: 0