הגנה ב-UNIX

 

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

 

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

 

למשל, נניח שלפנינו תרחיש הבא:

int n;

 

int *nptr;

 

 

nptr = &n;

 

  fork()

 

 

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

 

 

/* segf1.c - Demonstrate segmentation fault */

/* Under UNIX, we are no longer free to read / write wherever we please */

 

void main()

{

  int i, *iptr;

 

  iptr = &i;

 

  *iptr = 99;

 

  printf("\ni = %d, iptr = %p, *iptr = %d\n\n", i, iptr, *iptr);

 

 

  iptr = (int *) 256; /* Assign arbitrary value to pointer */

 

      /* if we can print this, then assignment was OK */

  printf("Pointer Assignment OK: iptr = %p\n\n", iptr);

   

 

  i = *iptr; /* Read from arbitrary pointer */

 

      /* if we can print this, then read was OK */

  printf("Pointer read OK: iptr = %p, i = %d\n\n", iptr, i);

 

  *iptr = 99;

 

      /* if we can print this, then write was OK */

  printf("Pointer Write OK:  i = %d, iptr = %p, *iptr = %d\n\n",

       i, iptr, *iptr);

 

 

} /* main */

 

__________________________________________________

 

math1:/home/ronn/OS > ./a.out

 

i = 99, iptr = 0xbffffa84, *iptr = 99

 

Pointer Assignment OK: iptr = 0x100

 

Segmentation fault (core dumped)

math1:/home/ronn/OS >

 

 

/* memdemo2.c - demonstrate virtual mode addressing - UNIX */

 

#include <stdio.h>

 

int n = 100;

 

void main()

{

  int id, *nptr;

 

  nptr = &n;

  if ( ( id =  fork() ) == 0 )

  {  /* select child process */

     puts("**************  child process ***********\n");

 

     n = 999;

 

     printf("PID is %d and ID is %d.\n", getpid(), id);

     printf("n is %d, *nptr is %d and nptr is %p.\n", n, *nptr, nptr);

     puts("\n**************  child process ***********\n");

    

     sleep(6);

 

     puts("**************  child process ***********\n");

     printf("PID is %d and ID is %d.\n", getpid(), id);

     printf("n is %d, *nptr is %d and nptr is %p.\n", n, *nptr, nptr);

     puts("\n**************  child process ***********\n");

  

     exit(0);

  }

 

 

     sleep(5);

     puts("**************  parent process ***********\n");

     printf("PID is %d and ID is %d.\n", getpid(), id);

     printf("n is %d, *nptr is %d and nptr is %p.\n", n, *nptr, nptr);

     puts("\n**************  parent process ***********\n");

 

     *nptr = 555;

 

     puts("**************  parent process ***********\n");

     printf("PID is %d and ID is %d.\n", getpid(), id);

     printf("n is %d, *nptr is %d and nptr is %p.\n", n, *nptr, nptr);

     puts("\n**************  parent process ***********\n");

 

 

}

 

--------------------------------------------------------------------------

 

mathcs22:/home4/ronn/OS > cc memdemo2.c

mathcs22:/home4/ronn/OS > a.out

**************  child process ***********

 

PID is 14878 and ID is 0.

n is 999, *nptr is 999 and nptr is 10000000.

 

**************  child process ***********

**************  parent process ***********

 

PID is 14877 and ID is 14878.

n is 100, *nptr is 100 and nptr is 10000000.

 

**************  parent process ***********

 

**************  parent process ***********

 

PID is 14877 and ID is 14878.

n is 555, *nptr is 555 and nptr is 10000000.

 

**************  parent process ***********

 

mathcs22:/home4/ronn/OS > **************  child process ***********

 

PID is 14878 and ID is 0.

n is 999, *nptr is 999 and nptr is 10000000.

 

**************  child process ***********

 

 

mathcs22:/home4/ronn/OS >