ΠŸΡ€ΠΎΠ΅ΠΊΡ‚ ΠΏΠΎ ΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° изоляции 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.com -p ‘stdio rpath inet thread’ curl http://example.com».

Π£Ρ‚ΠΈΠ»ΠΈΡ‚Π° 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_K, ~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_JMP | 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, SECCOMP_RET_ALLOW), /*L13*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)), /*L14*/ /* next filter */ };

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: opennet.ru