Проект із портування механізму ізоляції pledge для Linux

Автор стандартної Си-бібліотеки Cosmopolitan та платформи Redbean оголосив про реалізацію механізму ізоляції pledge() для Linux. Спочатку pledge розроблений проектом OpenBSD і дозволяє вибірково заборонити додаткам звернення до системних дзвінків, що не використовуються (для програми формується подібність білого списку системних дзвінків, а решта дзвінків забороняються). На відміну від доступних у Linux механізмів обмеження доступу до системних викликів, таких як seccomp, механізм pledge спочатку розроблений з огляду на максимальне спрощення застосування.

Ініціатива ізоляції додатків базового оточення OpenBSD, що завершилася невдачею, з використанням механізму systrace показала, що ізоляція на рівні окремих системних викликів занадто складна і трудомістка. В якості альтернативи був запропонований pledge, який дозволяв створювати правила ізоляції, не вникаючи в деталі та маніпулюючи готовими класами доступу. Наприклад, пропонуються класи stdio (введення/виведення), rpath (тільки читання файлів), wpath (запис файлів), cpath (створення файлів), tmppath (робота з тимчасовими файлами), inet (мережеві сокети), unix (unix-сокети) , dns (резолвінг у DNS), getpw (доступ на читання до бази користувачів), ioctl (виклик ioctl), proc (управління процесами), exec (запуск процесів) та id (управління правами доступу).

Правила роботи із системними дзвінками задаються у формі анотацій, що включають список дозволених класів системних дзвінків та масив файлових шляхів, куди дозволено доступ. Після складання та запуску модифікованого додатка, ядро ​​бере на себе роботу з контролю за дотриманням заданих правил.

Окремо розвивається реалізація pledge для FreeBSD, яка відрізняється можливістю ізоляції додатків без внесення змін до їх коду, тоді як OpenBSD виклик pledge націлений на тісну інтеграцію з базовим оточенням і додавання анотацій в код кожного додатка.

Розробники порту pledge для Linux скористалися прикладом FreeBSD і замість внесення змін до коду підготували утиліту-надбудову pledge.com, що дозволяє застосувати обмеження без зміни коду програми. Наприклад, для запуску утиліти curl з відкриттям доступу тільки до класів системних викликів stdio, rpath, inet і threadstdio достатньо виконати ".

Утиліта pledge працює у всіх дистрибутивах Linux, починаючи з RHEL6, і не потребує root-доступу. Додатково на базі бібліотеки cosmopolitan надається API для керування обмеженнями в коді програм мовою Сі, що дозволяє в тому числі створювати анклави для вибіркового обмеження доступу в прив'язці до певних функцій програми.

Реалізація не вимагає внесення змін до ядра — обмеження pledge транслюються до правил SECCOMP BPF та обробляються за допомогою рідного для Linux механізму ізоляції системних викликів. Наприклад, виклик pledge(«stdio rpath», 0) буде перетворений на BPF-фільтр static const struct sock_filter kFilter[] = { /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, syscall, 0, 14 - 1), / * L1 * / BPF_STMT (BPF_LD | BPF_W | BPF_ABS, OFF (args [0])), / * L2 * / BPF_JUMP (BPF_JMP | BPF_JEQ | BPF_K, 2, 4 - 3, 0), / * L3 * / BPF_JUMP ( BPF_JMP | BPF_JEQ | BPF_K, 10, 0, 13 - 4), / * L4 * / BPF_STMT (BPF_LD | BPF_W | BPF_ABS, OFF (args [1])), / * L5 * / BPF_STMT (BPF_ALU | BPF_AND | BPF ~0x80800), / * L6 * / BPF_JUMP (BPF_JMP | BPF_JEQ | BPF_K, 1, 8 - 7, 0), / * L7 * / BPF_JUMP (BPF_JMP | BPF_JEQ | BPF_K, 2, 0, 13 - 8), / L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])), /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 12 - 10, 0), /*L10*/ BPF_JUMP( | BPF_JEQ | BPF_K, 6, 12 - 11, 0), / * L11 * / BPF_JUMP (BPF_JMP | BPF_JEQ | BPF_K, 17, 0, 13 - 11), / * L12 * / BPF_STMT (BPF_RET | BPF_K /*L13*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)), /*L14*/ /* next filter */ };

Джерело: opennet.ru

Додати коментар або відгук