שאלות נפוצות

האם אפשר להשתמש בשרשורים?

כן, שרשורים נתמכים ב-Sandbox2.

כל השרשורים צריכים לעבור לארגז חול

בגלל אופן הפעולה של Linux, המדיניות seccomp-bpf חלה על השרשור הנוכחי בלבד: המשמעות היא שהמדיניות לא תחול על שרשורים קיימים אחרים, אבל שרשורים עתידיים יירשו את המדיניות:

  • אם אתם משתמשים ב-Sandbox2 במצב הראשון שבו הרצה בארגז חול מופעלת לפני execve(), כל השרשורים יירשו את המדיניות ואין בעיה. זה המצב המועדף להרצה בארגז חול.
  • אם משתמשים במצב השני שבו להפעלה יש set_enable_sandbox_before_exec(false) ו-Sandboxee מודיע למנהל המערכת מתי הוא רוצה להעביר אותו לארגז החול באמצעות SandboxMeHere(), צריך לוודא שהמסנן מיושם על כל ה-threads. אחרת, יש סיכון לבריחה מ-Sandbox: קוד זדוני עלול לעבור משרשור בארגז חול לשרשור שלא פועל בארגז חול.

איך כדאי להדר את ה-Sandboxee שלי?

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

  • בצע הידור סטטי של הקובץ הבינארי של Sandboxee כדי להימנע מקישור דינמי שמשתמש בהרבה מערכות הפעלה (open/openat, mmap וכו').
  • מאחר ש-Bazel מוסיפה את pie כברירת מחדל, אבל הסטטית לא תואמת לו, כדאי להשתמש בדגל התכונות כדי לאלץ אותה להשבית אותה באמצעות האפשרויות הבאות בכללי cc_binary:

    linkstatic = 1,
    features = [
        "fully_static_link",  # link libc statically
        "-pie",
    ],
    

עם זאת: השימוש בסטטי הוא החיסרון של צמצום אנטרופיה של ערימה (heap) של ASLR (מ-30 ביטים ל-8 ביטים), וכך קל יותר לנצל את ההזדמנויות. החליטו היטב מה עדיף בהתאם ליישום ולמדיניות של ארגז החול:

  • לא סטטי: ASLR טוב של ערימה. יכול להיות שיהיה קשה יותר לבצע קוד ראשוני, אבל במחיר של מדיניות Sandbox פחות יעילה, אולי יהיה קל יותר לפרוץ אותה.
  • static: ASLR של ערימה (heap ASLR) שגוי. ייתכן שקל יותר לבצע קוד ראשוני, אך מדיניות Sandbox יעילה יותר, שקשה יותר לפרוץ אותה.

לצערנו, בחרתי לעשות את זה כיוון שהמהדר לא תומך ב-PIE סטטי (עמדה של קובצי הפעלה עצמאיים). PIE מיושם באמצעות הקובץ הבינארי כאובייקט דינמי, והטוען דינמי ממפה אותו במיקום אקראי לפני הפעלתו. לאחר מכן, מכיוון שהערימה (heap) ממוקמת בדרך כלל בקיזוז אקראי אחרי הכתובת הבסיסית של הקובץ הבינארי (והמורחבת באמצעות brk syscall), פירוש הדבר הוא שעבור קבצים בינאריים סטטיים, האנטרופיה של ערימה (heap ASLR) מבוססת רק על הקיזוז הזה מפני שאין PIE.

כדי לראות דוגמאות לאפשרויות ההידור האלה, אפשר לעיין בדוגמה הסטטית BUILD.bazel: static_bin.cc הוא הידור סטטיסטי, ולכן המדיניות שלנו מבוססת מאוד. זה עובד גם טוב להרצה בארגז חול (sandboxing) של קבצים בינאריים של צד שלישי.

האם אפשר להשתמש בקבצים בינאריים של sandbox 32-bit x86 ב-Sandbox?

Sandbox2 יכול לשמור בארגז חול רק את אותה ארכיטקטורה שבה הוא נוצר.

בנוסף, הופסקה התמיכה ב-32-bit x86 ב-Sandbox2. אם תנסו להשתמש בקובץ הפעלה של 64-bit x86 כדי לבצע בארגז החול קובץ הרצה של 32 סיביות של x86, או קובץ בינארי של 64 סיביות של x86 שיוצר שיחות מערכת (syscalls) של 32 ביט (באמצעות int 0x80), שניהם יגרמו להפרה ב-Sandbox שניתנת לזיהוי לפי תווית הארכיטקטורה [X86-32].

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

האם יש מגבלות על מספר ארגזי החול מתהליך הפעלה יכול לבקש?

לכל מופע של Sandboxee (תהליך חדש שנוצר מה-forkserver), נוצר שרשור חדש – כאן נמצאת המגבלה.

האם מנהל מערכת יכול לבקש יצירה של יותר מ-Sandbox אחד?

לא. יש יחס של 1:1 – מכונת ביצוע מאחסנת את ה-PID של ה-Sandboxee, מנהלת את מכונת התקשורת למכונה של Sandbox וכו'.

למה מופיעה ההודעה "הפונקציה לא מיושמת" ב-forkserver.cc?

Sandbox2 תומך רק בהפעלה על ליבות חדשות במידה סבירה. נקודת החיתוך הנוכחית שלנו היא הליבה 3.19, אם כי היא עשויה להשתנות בעתיד. הסיבה לכך היא שאנחנו משתמשים בתכונות ליבה חדשות יחסית, כולל מרחבי שמות של משתמשים ו-seccomp עם דגל TSYNC.

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

אם אתה משתמש ב-Debian או ב-Ubuntu, עדכון הליבה קל באותה מידה כמו הפעלת:

sudo apt-get install linux-image-<RECENT_VERSION>