سؤال

لقد تعثرت مؤخرا عبر مقالة الذي يدعي أن Microsoft تحظر memcpy() تعمل في محلات البرمجة الآمنة.أدرك نقاط الضعف الكامنة في الوظيفة، ولكن هل من الضروري حظر استخدامها بالكامل؟

هل يجب تجنب البرامج التي أكتبها؟ memcpy() بالكامل أم مجرد ضمان استخدامه بأمان؟ما هي البدائل الموجودة التي توفر وظائف مماثلة ولكنها أكثر أمانًا؟

هل كانت مفيدة؟

المحلول

توفر مايكروسوفت البدائل إلى memcpy وwmemcpy للتحقق من صحة المعلمات الخاصة بهما.

يقول memcpy_s، "حسنًا، قبل أن أقرأ من هذا العنوان، اسمح لي أن أتحقق بنفسي من أنه ليس مؤشرًا فارغًا؛وقبل أن أكتب إلى هذا العنوان، سأجري هذا الاختبار مرة أخرى.سأقوم أيضًا بمقارنة عدد البايتات التي طُلب مني نسخها بالحجم المطالب به للوجهة؛إذا وفقط إذا اجتازت المكالمة جميع هذه الاختبارات، فسأقوم بإجراء النسخة."

يقول memcpy "قم بحشو الوجهة في سجل ، وقم بحشو المصدر في سجل ، وقم بحشو العد في سجل ، وقم بإجراء MOVSB أو MOVSW." (مثال على المدن الجغرافية ، ليس طويلا لهذا العالم: http://www.geocities.com/siliconvalley/park/3230/x86asm/asml1013.html)

يحرر:على سبيل المثال في البرية أمنيتك هي أمري نهج memcpy، فكر في OpenSolaris، حيث يكون memcpy (في بعض التكوينات) محددة من حيث bcopy, ، و com.bcopy (لبعض التكوينات) هو ...

void
     33 bcopy(from, to, count)
     34 #ifdef vax
     35     unsigned char *from, *to;
     36     int count;
     37 {
     38 
     39     asm("   movc3   12(ap),*4(ap),*8(ap)");
     40 }
     41 #else
     42 #ifdef u3b      /* movblkb only works with register args */
     43     unsigned char *from, *to;
     44     int count;
     45 {
     46     asm("   movblkb %r6, %r8, %r7");
     47 }
     48 #else
     49     unsigned char *from, *to;
     50     int count;
     51 {
     52     while ((count--) > 0)
     53         *to++ = *from++;
     54 }
     55 #endif

يحرر:شكرا ميلي سميث!إليك ما كان موجودًا في صفحة المدن الجغرافية التي قمت بربطها أعلاه:

MOVS

يتم استخدام تعليمات movs لنسخ سلسلة المصدر إلى الوجهة (نعم، نسخ، وليس نقل).تحتوي هذه التعليمات على نوعين مختلفين:موفسب و موفسو.يقوم movsb ("نقل سلسلة البايت") بنقل بايت واحد في كل مرة، بينما ينقل movsw بايتين في المرة الواحدة.

نظرًا لأننا نرغب في نقل عدة بايتات في المرة الواحدة، فإن تعليمات النقل هذه تتم على دفعات باستخدام بادئة مندوب.يتم تحديد عدد الحركات بواسطة سجل CX.انظر المثال أدناه:

:
lds   si, [src]
les   di, [dest]
cld
mov   cx, 100
rep   movsb
:

سيقوم هذا المثال بنسخ 100 بايت من src إلى dest.إذا قمت باستبدال movsb بـ movsw، فإنك تنسخ 200 بايت بدلاً من ذلك.إذا قمت بإزالة بادئة مندوب، فلن يكون لسجل CX أي تأثير.سوف تقوم بنقل بايت واحد (إذا كان movsb، أو 2 بايت إذا كان movsw).

نصائح أخرى

وبالمنشار، إذا ما استخدمت بشكل صحيح، هو آمن. نفس الشيء مع memcpy (). ولكن في كلتا الحالتين، إذا كنت أصاب الأظافر، فإنه يمكن أن تطير ويضر بك.

وباختصار، memcpy () مطلوب للحوسبة على مستوى منخفض، وسوف لا تذهب بعيدا، ولكن للبرمجة رفيعة المستوى التي لا تحتاج إليها. ليس هناك memcpy () في بايثون.

ولا تهتم. بدائل مايكروسوفت التي ليست أفضل بكثير. قيمة الرئيسي هو أن هذه التعليمات البرمجية تسبب لتصبح unportable لينكس. مايكروسوفت صنع المزيد من المال على OS يبيعونها لعملائك من يجعلون على نسخة من Visual C ++ التي اشتريتها.

وتصف المادة نفسها أكثر أمنا بديل: memcpy_s، الذي يتطلب منك تحديد الحد الأقصى لطول الهدف. عندما يتم توفير هذا العدد مستقلة عن كمية من وحدات البايت لنسخ، وهو يعمل كحاجز لمنع تجاوز سعة المخزن المؤقت. بالطبع، يمكنك استغلال هذه بإعطاء نفس العدد على حد سواء.

هل حظر memcpy () في قانون بلدي صنع لي مبرمج أفضل وأكثر أمانا طلبي أو أكثر عدلا تتعارض؟ أنا غير مؤكد، إذا MS يريد حقا لتغيير أي شيء أو مجرد تقديم أي رمز C جديد غير متوافق مع المجمعين أخرى. بالمناسبة. MS يفعل ذلك حيلة على العديد من الوظائف وانها مزعج جدا. strcpy -> strcpy_s -> StringCchCopy

وأعتقد أن C يجب ترك الخيار للمبرمج لاطلاق النار قدمه الخاصة. إدارة الذاكرة اليدوية آمنة في حال القيام به بشكل صحيح.

ولقد قلت ذلك بنفسك: "مايكروسوفت حظر ظيفة memcpy () في تقريرها على محلات البرمجة الآمنة ، أو أفهم على نقاط الضعف الكامنة في وظيفة ، أو"

ومن المعروف أن

memcpy () وعدد كبير من الوظائف القياسية الأخرى أن تسبب الضعف، فلماذا متجر برمجة آمنة تسمح استخدامها عندما يكون (ولو تدريجي) تحسين تافهة؟

لا شك في جهودها الرامية إلى تحسين أمن المنتجات الخاصة بهم، أشار مراجعة الكود بوضوح أن هذه الوظائف هي المسؤولة عن نسبة كبيرة من الضعف، عازلة الفيضانات الخ وبدلا من جعل مغلفة للاستخدام الداخلي فقط قدموا لهم في المكتبة القياسية وأضافت مترجم تحذير (لا حظر) لصالح الجميع.

إذا كنت تستخدم الإصدارات القديمة، مثل C99 أو C ++ 98، أو على سولاريس، لا يمكنك استخدام memcpy_s، إلا إذا كان لديك مكتبة الآمن C مثبتة.

وmemcpy_s () هو تطبيق Microsoft محددة لا وجود له على MS غير التنفيذ، بما في ذلك ANSI، قبل C11، في المعايير الخاصة بها.

وسأترك الاشياء المؤيدة للMS ومكافحة MS جانبا، لأنه غير ذي صلة.

وmemmove () هو الحل الأفضل على أي حال لأنها تعالج قضية التداخل. memmove_s () هو أكثر قوة، ولكن مرة أخرى، إلا إذا كنت في C11 أو في وقت لاحق.

والبديل هو الدعوة memcpy_s

وكنت من المفترض أن استخدام memcpy_s () بدلا من ذلك. نفس النوع من الإصدارات _s موجودة لمجموعة متنوعة من الوظائف الأخرى التي تعتبر غير آمن.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top