השחתת זיכרון

מתוך ויקיפדיה, האנציקלופדיה החופשית
קפיצה אל: ניווט, חיפוש

השחתת זיכרון (Memory corruption) הוא סוג של באג, אשר קורה כאשר מיקום בזיכרון מחשב או אוגר משוכתב באופן מקרי ולא מבוקר, כתוצאה משגיאה בתוכנית, תקלה בחומרה (Hard Error) או אירוע חיצוני הגורם לשינוי תוכן הזיכרון (Soft Error). טעות כזו יכולה לגרום לקריסה מיידית של התוכנה (למשל במקרה של כתיבה לכתובת 0, התוכנית תיזרק על ידי מערכת ההפעלה בעקבות שגיאת סגמנטציה). מנגד, ייתכן גם שהשגיאה לא תבוא לידי ביטוי למשך זמן רב, ורק עבור קלטים מסוימים יופיע פלט שגוי.

דוגמה בולטת להשחתת זיכרון היא ניסיון גישה לתא במערך כאשר הוא אינו קיים. בעיה זו ניתן למצוא במרבית שפות התכנות, בחלקן תהיה הודעת שגיאה ובחלק - לא. למשל בשפת התכנות C, תאים במערך מקבלים ערכים סדורים החל מ־0 ולא מ־1, ולכן למעשה התא ה־n (והאחרון) מקבל את התווית 1-n. טעות תכנותית נפוצה היא ניסיון כתיבה לתא הלא קיים n, דבר אשר גורם להשחתת זיכרון שלא בניהול המערך (אם כי, יש לציין שרוב הסיכויים שהזיכרון הנפגע שייך לתוכנית הרצה ולא למערכת ההפעלה, כך שאין סכנה ממשית לתפקוד המחשב).

תקיפה זדונית של הצפת מערך (Buffer Overflow)[עריכת קוד מקור | עריכה]

השחתת זיכרון עשויה להיות גם חור אבטחה. התקיפה הנפוצה ביותר מסוג זה מכונה "הצפת מערך".

בתכנות, כאשר קוראים לפונקציה מתוך תוכנית, למעשה עוצרים את רצף הקוד הנוכחי כדי לבצע סדרה של פקודות שנמצאת במקום אחר (שבו מוגדרת הפונקציה). המעבד "קופץ" משורת הקוד שקראה לפונקציה אל שורת הקוד הראשונה של הפונקציה, ושומר מספר פרמטרים על גבי המחסנית שמשמשת את התהליך. פרמטרים אלה הם פרטים שהפונקציה צריכה כדי לפעול, ובנוסף להם צריך לשמור גם את כתובת החזרה, על מנת שבסיום ביצוע הפונקציה המעבד יוכל "לקפוץ" חזרה למקום שממנו הפונקציה נקראה ולהמשיך לבצע את הקוד של התוכנית. כל הפרמטרים האלה וגם המשתנים הפנימיים של הפונקציה מוגדרים על המחסנית, ושם מוקצה להם כמות הזיכרון הדרושה להם.

פונקציות שמתעסקות עם קלט שמושם לתוך מערכים ולא בודקות את גודלם לפני שהן מבצעות את ההשמה חשופות להתקפה של הצפת מערך. אחד הפרמטרים שניתנים לפונקציה במקרה זה הוא התוכן שיש לשים במערך. התוקף יבקש למלא את המערך בתוכן שהוא בכוונה גדול מאוד, גדול יותר מהממדים של המערך.

כאשר הפונקציה מנסה למלא את המערך בתוכן שקיבלה, נגמר לה המקום במערך לפני שנגמר התוכן למילוי. מאחר שהיא מבצעת את ההשמה בלי לבדוק, היא תמשיך למלא את המחסנית בתוכן ותדרוס נתונים אחרים שנכתבו בה. הקלט הזדוני דורס בכוונה את כתובת החזרה מהפונקציה עם הכתובת של תחילת אותו מערך. בצורה זו, כשיסתיים ביצוע הפונקציה, המעבד "יקפוץ" לא להמשך התוכנית שקראה לה, אלא לתחילת המערך, ויתחיל להתייחס לנתונים שבמערך בתור פקודות לביצוע. הפקודות הללו יכולות להיות כל דבר שהוא, ולכן התוקף למעשה יכול לבצע כל שברצונו על המחשב שהריץ את התוכנית הזו.

התמודדות עם השחתת זיכרון[עריכת קוד מקור | עריכה]

בשפות תכנות מסוימות, כגון Java מתבצעת בדיקה אוטומטית לתחומי המערך, ובדרך כלל ניסיון להשחתת זיכרון יוציא הודעת שגיאה. בנוסף, קיימים כלי תכנות אשר מזהים טעויות של גישה מעבר לגבולות מערך באופן אוטומטי, כגון Valgrind.

כיוון שמרבית התוכנות המסחריות מורכבות מקובצי מקור שונים שיצאו תחת ידיהם של מתכנתים שונים, זיהוי באגים אלה הופך לכמעט בלתי אפשרי, וגם פוגע בעקרון ההכמסה של תכנות מונחה עצמים.

ראו גם[עריכת קוד מקור | עריכה]

קישורים חיצוניים[עריכת קוד מקור | עריכה]