فا

‫ برنامه‌نويسي امن با زبان C – قوانين و پيشنهادات تكميلي – قسمت آخر

IRCAR201111123
عنصر اصلي در برنامه‌نويسي امن با زبان‌هاي مختلف برنامه‌نويسي، مستندسازي خوب و استفاده از استانداردهاي قابل اجرا است. استانداردهاي كدنويسي، برنامه‌نويسان را ترغيب به پيروي از مجموعه‌اي متحدالشكل از قوانين و راهنمايي‌هايي مي‌كند كه بر اساس نيازمندي‌هاي پروژه و سازمان تعيين شده است، نه بر اساس سلايق و مهارت‌هاي مختلف برنامه‌نويسان. به محض تعيين استانداردهاي مذكور، ميتوان از آن به عنوان معياري براي ارزيابي كدهاي منبع، چه به صورت دستي و چه به صورت اتوماتيك استفاده كرد.
از استانداردهاي معروف در اين زمينه مي‌توان به استانداردCERT براي كدنويسي امن اشاره كرد كه يك سري از قوانين و پيشنهادات را براي كدنويسي امن با زبان‌هاي برنامه‌نويسي C، C++ و جاوا ارائه مي‌دهد. هدف از اين قوانين و پيشنهادات، حذف عادت‌هاي كدنويسي ناامن و رفتارهاي تعريف نشده است كه منجر به آسيب‌پذيري‌هاي قابل سوءاستفاده مي‌شود. به كارگيري استانداردهاي مذكور منجر به توليد سيستم‌هاي با كيفيت بالاتر مي‌شود كه در برابر حملات بالقوه، پايدارتر و مقاوم‌تر هستند.
در مقاله‌هاي قبلي، كليات استاندارد CERT در زمينه مزبور را توضيح داديم و در سري مقاله‌هاي برنامه‌نويسي امن به زبان C به صورت تخصصي‌تر شيوه برنامه‌نويسي امن با اين زبان را مورد بررسي قرار مي‌دهيم. قابل ذكر است كه در اين استاندارد 89 قانون و 134 پيشنهاد براي برنامه‌نويسي امن با زبان C ارائه شده است كه در اين سري مقالات، مهمترين آنها را كه در سطح يك قرار دارند، شرح خواهيم داد. براي كسب اطلاعات بيشتر در مورد سطح‌بندي قوانين و پيشنهادات به مقاله "آشنايي با استاندارد CERT براي برنامه نويسي امن" مراجعه فرماييد. سري مقالات حاضر با عنوان قوانين و پيشنهادات تكميلي (Miscellaneous) آخرين سري مقالات برنامه‌نويسي امن به زبان C است كه در آن قوانين و پيشنهاداتي توضيح داده مي‌شوند كه در دسته بندي‌هاي قبلي نگنجيده‌اند.
47. MSC36-C – هيچ عبارت اجرايي را در دستور switch قبل از case اول قرار ندهيد.
هيچ عبارت اجرايي را در دستور switch قبل از برچسب case اول قرار ندهيد، زيرا اين عبارت ها هيچ گاه اجرا نشده و توسط كامپايلر ناديده گرفته مي شوند.
در صورتي كه برنامه نويس متغيرها را قبل از case تعريف كرده و آنها را مقداردهي اوليه كند و سپس در صدد استفاده از آنها درون هر يك از عبارت هاي case باشد، آن متغيرها درون حوزه switch شناخته شده هستند ولي در واقع مقداردهي اوليه نشده و حاوي مقادير نامشخصي مي باشند.
در زير قطعه كدي را مي بينيد كه از قانون فوق پيروي نكرده و حاوي دستورات اجرايي قبل از اولين case درون دستور switch است.

زماني كه برنامه بالا اجرا مي شود در صورتي كه مقدار i صفر باشد خروجي عدد 17 و در صورتي كه مقدار i غير صفر باشد خروجي نامعلوم خواهد بود. همچنين فراخواني f() هيچگاه انجام نخواهد شد.
در زير برنامه اصلاح شده فوق را مي بينيد، عبارت هاي اجرايي كه در بالا قبل از اولين برچسب case بودند، قبل از دستور switch قرار گرفته و قابليت پيش بيني و خوانايي كد را افزايش مي دهند.

48. MSC36-C – قبل از استفاده از تابع realloc() از تراز حافظه اطلاع پيدا كنيد.
در صورتي كه اشاره گر ptr با ترازي (alignment) كه از تابع aligned_alloc بازگشته است مقداردهي شده باشد و realloc() دوباره آن را با تراز ديگري مقداردهي كند، رفتار برنامه تعريف نشده خواهد بود.
نكته: اين قانون تنها در مورد كامپايلرهايي كه بنا بر استاندارد C1X ايجاد شده اند، كاربرد دارد.
در زير برنامه اي را مشاهده مي كنيد كه در آن ptr به يك حافظه 4096 بايتي اختصاص داده شده است، در حالي كه تابع realloc() آن را به تراز ديگري اختصاص مي دهد.
در اينجا رفتار برنامه تعريف نشده است زيرا ترازي كه realloc() اختصاص مي دهد متفاوت از آن چيزي است كه aligned_alloc() انجام مي دهد.

نتيجه اجراي برنامه فوق به صورت زير است:
memory aligned to 4096 bytes
ptr = 0x1621b000
After realloc():
ptr1 = 0x1621a010
همان طور كه مشاهده مي كنيد ptr1 بعد از اجراي تابع realloc() ديگر به ضريب حافظه 4096 بايتي اختصاص ندارد.
در برنامه اصلاح شده زير يك تابع realloc() متوازن پياده سازي شده است. اين تابع به اندازه متغير resize بايتهايي را به حافظه جديد با همان تراز (alignment ) حافظه قديمي اختصاص مي دهد و در نهايت حافظه قديمي را آزاد مي سازد.

اين مقاله، آخرين قسمت از سري مقاله هاي برنامه نويسي امن با زبان c است. در زير لينك قسمت هاي قبلي آورده شده است:

نظرات

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

نوشته

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

دسته‌ها

امتیاز

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