לדלג לתוכן

10.1 - זהויות ובדיקת גישה בלינוקס - פתרון

פתרון שכבות ההרשאה

פתרון ראשון - אין נפילה להרשאת אחרים

כאשר התיקייה נשארת במצב 0700 והקובץ מקבל מצב אפס, פתיחה חדשה נכשלת בגלל הרשאות הקובץ, בעוד שהמתאר הפתוח ממשיך לקרוא. כדי לבדוק את רשומת הבעלים, שנו את מצב הקובץ ל־0004 ונסו לפתוח אותו מחדש תחת אותו משתמש רגיל.

fs::set_permissions(&lab.directory, Permissions::from_mode(0o700))?;
fs::set_permissions(&lab.file, Permissions::from_mode(0o004))?;
assert_eq!(File::open(&lab.file).unwrap_err().kind(), io::ErrorKind::PermissionDenied);

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

פתרון שני - מסכה בזמן יצירה

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

use std::fs::{self, OpenOptions};
use std::io;
use std::os::unix::fs::{OpenOptionsExt, PermissionsExt};

struct Mask(libc::mode_t);
impl Drop for Mask {
    fn drop(&mut self) { unsafe { libc::umask(self.0); } }
}

fn main() -> io::Result<()> {
    let _mask = Mask(unsafe { libc::umask(0o077) });
    let path = format!("umask-item-{}", std::process::id());
    let file = OpenOptions::new().write(true).create_new(true).mode(0o666).open(&path)?;
    let mode = file.metadata()?.permissions().mode() & 0o777;
    drop(file);
    fs::remove_file(&path)?;
    assert_eq!(mode, 0o600);
    Ok(())
}

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

פתרון שלישי - כשל עוצר את המעבר

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

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