Яд­ро Linux раз­вива­ется семимиль­ными шагами. В нем появ­ляют­ся все новые и новые фун­кции. Закон­чился еще один год, и мы тра­дици­онно дела­ем их обзор.
 

Введение

Для начала нем­ного ста­тис­тики. За 2014 год:

  • Выш­ло шесть мажор­ных вер­сий ядра (с 3.13 по 3.18).
  • В общей слож­ности было выпуще­но 74 691 пат­чсет (в сред­нем по 12 449 на каж­дую мажор­ную вер­сию).
  • В сред­нем в ядро за 2014 год внес­ли свой вклад 1495 людей.
  • Пер­вые мес­та по количес­тву изме­нений ста­биль­но занима­ют Intel и Red Hat.
Статистика коммитов в ядро
Ста­тис­тика ком­митов в ядро
Встроенный в последние версии ядер отладчик в случае сбоя позволяет узнать некоторую полезную информацию
Встро­енный в пос­ледние вер­сии ядер отладчик в слу­чае сбоя поз­воля­ет узнать некото­рую полез­ную информа­цию

Пос­мотрим, что же нового появи­лось за этот год.

 

Сетевая подсистема

Са­мым явным новов­ведени­ем в сетевой под­систе­ме выг­лядит, пожалуй, при­ходя­щий на замену iptables nftables. Дело в том, что iptables слиш­ком лине­ен, и это огра­ничи­вает его гиб­кость. Разуме­ется, сущес­тву­ют обер­тки вок­руг него (такие, нап­ример, как не раз и не два упо­минав­ший­ся мной Shorewall), но они выпол­няют­ся в поль­зователь­ском прос­транс­тве, что при наличии десят­ков тысяч под­клю­чений соз­дает немалый overhead.

Nftables пред­став­ляет собой неч­то ана­логич­ное BPF: ути­лита nft ком­пилиру­ет пра­вила в байт‑код и переда­ет его в ядро. Это поз­воля­ет не толь­ко зна­читель­но улуч­шить гиб­кость, но и умень­шить количес­тво кода ядра. Так, отпа­дает надоб­ность в реали­зации рас­ширений режима ядра для под­дер­жки вся­кого вновь появ­ляюще­гося про­токо­ла. В качес­тве же базовых «кир­пичиков» выс­тупа­ют эле­мен­ты ста­рого доб­рого Netfilter, такие как хуки.

Настройка ядра. Включаем nftables
Нас­трой­ка ядра. Вклю­чаем nftables
Сборка ядра
Сбор­ка ядра

Син­таксис ути­литы nft, одна­ко, отли­чает­ся от син­такси­са ста­рых ути­лит и пред­став­ляет собой иерар­хичес­кий язык, более под­ходящий для опи­сания пра­вил, нежели линей­ный стиль iptables. Пар­сер для это­го язы­ка сге­нери­рован с помощью BISON.

Просматриваем таблицы nftables
Прос­матри­ваем таб­лицы nftables

Сам же BPF (встро­енный в ядро) обза­вел­ся новым JIT-ком­пилято­ром, минималь­ным отладчи­ком и теперь делит­ся на два набора инс­трук­ций: «клас­сичес­кий» и «внут­ренний». Пос­ледний работа­ет быс­трее за счет того, что боль­ше сов­местим с реаль­ным машин­ным кодом. «Внут­ренняя» реали­зация BPF пред­назна­чена исклю­читель­но для работы в режиме ядра — код из «клас­сичес­кой» тран­сли­рует­ся в нее перед пер­вым запус­ком. Есть так­же пла­ны по исполь­зованию BPF в дру­гих под­систе­мах, не толь­ко в сетевой. В час­тнос­ти, seccomp-bpf уже его исполь­зует.

Исходный код ядерной части BPF
Ис­ходный код ядер­ной час­ти BPF

Усо­вер­шенс­тво­вали так­же и ipset: теперь он под­держи­вает network namespaces, что поз­воля­ет исполь­зовать его в LXC. Добав­лена и под­дер­жка ком­мента­риев и еще некото­рые полез­ные мелочи.

Внут­реннос­ти сетевой под­систе­мы тоже пре­тер­пели некото­рые изме­нения. Так, были вне­сены изме­нения, поз­воля­ющие отправ­лять мел­кие пакеты сра­зу груп­пами (при соот­ветс­тву­ющей под­дер­жке драй­вера и сетевой кар­ты); это поз­воля­ет раз­гру­зить сетевой стек и даже на обыч­ном компь­юте­ре дос­тигнуть ско­рос­ти переда­чи в 40 Гбит/с.

По­мимо это­го, был реали­зован механизм FOU — foo over UDP, поз­воля­ющий орга­низо­вывать вся­чес­кие тун­нели поверх UDP. Это может понадо­бить­ся для некото­рых спе­цифи­чес­ких слу­чаев; нап­ример, отдель­ные ком­мутато­ры и сетевые кар­ты пре­дос­тавля­ют механиз­мы быс­трой обра­бот­ки пакетов толь­ко для UDP.

Был так­же реали­зован и про­токол Geneve, поз­воля­ющий инкапсу­лиро­вать в пакеты абс­трак­ции, необ­ходимые для вир­туали­зации сети, — для облачных нужд (мар­шру­тиза­ция сег­ментов, к при­меру). Сущес­тво­вав­шие до это­го про­токо­лы (VXLAN и NVGRE) ока­зались слиш­ком заточе­ны под кон­крет­ные тре­бова­ния.

 

Файловые системы и блочные устройства

В под­систе­ме блоч­ных устрой­ств и фай­ловых сис­тем тоже дос­таточ­но мно­го изме­нений. В час­тнос­ти, был реали­зован новый механизм, который обес­печива­ет более быс­трую работу с SSD-накопи­теля­ми. Это дос­тига­ется путем дву­хуров­невой модели оче­редей: оче­реди пер­вого уров­ня рас­пре­деля­ются по про­цес­сорам/ядрам, а оче­реди вто­рого управля­ют обра­щени­ями к накопи­телям; таким обра­зом, количес­тво про­цес­соров может теперь вли­ять на под­систе­му вво­да/вывода дос­таточ­но силь­но.

Ис­сле­дова­ния показа­ли, что новый механизм теперь может обес­печить мил­лионы зап­росов вво­да/вывода в секун­ду, — срав­ни со ста­рым, пиковая про­изво­дитель­ность которо­го была все­го лишь око­ло 800 тысяч IO-зап­росов в секун­ду. Конеч­но, во вре­мена жес­тких дис­ков про­изво­дитель­нос­ти ста­рого механиз­ма хва­тало с лих­вой, одна­ко с появ­лени­ем SSD-накопи­телей его недос­татки ста­ли оче­вид­ны.

В под­систе­ме bcache, которая исполь­зует SSD-накопи­тели в качес­тве кеша к обыч­ным HDD, перепи­сан сбор­щик мусора — теперь он инкре­мен­таль­ный. Это поз­волило свес­ти к миниму­му задер­жки при очис­тке кеша. В модуле же dm-cache, выпол­няющем прак­тичес­ки те же фун­кции, добав­лен режим сквоз­ного проб­роса, который при­меня­ется, ког­да неиз­вес­тно, нас­коль­ко содер­жимое кеша акту­аль­но. В дан­ном режиме все опе­рации чте­ния исполь­зуют жес­ткий диск нап­рямую, а запись про­исхо­дит на накопи­тель, задан­ный для кеширо­вания.

В FUSE реали­зован writeback-кеш, что дела­ет дан­ную под­систе­му про­изво­дитель­нее в ситу­ациях с интенсив­ной записью.

Ус­корена работа с фай­ловой сис­темой SquashFS, исполь­зуемой, как пра­вило, в Live CD. Реали­зова­на, к при­меру, рас­паков­ка в кеш стра­ниц нап­рямую, что поз­воля­ет избе­жать лиш­них нак­ладных рас­ходов и сущес­твен­но уве­личи­вает ско­рость — некото­рые тес­ты показы­вают чуть ли не шес­тикрат­ное уве­личе­ние.

В BTRFS наконец появи­лась воз­можность под­монти­ровать отдель­ные под­тома как в режиме RO-, так и RW. Кро­ме того, добав­лена опция --commit, поз­воля­ющая ука­зывать интервал ком­митов на диск и некото­рые дру­гие полез­ности.

XFS теперь под­держи­вает опцию O_TMPFILE, вве­ден­ную в сис­темный вызов open() в сен­тябре 2013-го и слу­жащую для соз­дания безымян­ных вре­мен­ных фай­лов, что поз­воля­ет сни­зить риск воз­никно­вения соот­ветс­тву­ющих уяз­вимос­тей. Во‑вто­рых, был добав­лен B+ tree индекс для сво­бод­ных ино­дов — с целью уско­рения их выделе­ния.

По­яви­лась пол­ноцен­ная под­дер­жка OverlayFS — «двух­слой­ной» фай­ловой сис­темы, ниж­ний слой которой обыч­но находит­ся на read-only-носите­лях, а на вер­хний мож­но спо­кой­но писать, не бес­поко­ясь о том, что на самом деле это уже сов­сем дру­гая фай­ловая сис­тема. Подоб­ные ФС полез­ны, нап­ример, в усо­вер­шенс­тво­ван­ных про­шив­ках для роуте­ров, таких как OpenWRT, где ниж­ним сло­ем явля­ется та же SquashFS, а вер­хним — либо выделен­ная часть флеш‑памяти, либо же USB-накопи­тель. Отли­чие от ана­логов — все фай­ловые опе­рации пос­ле откры­тия фай­ла про­изво­дят­ся нап­рямую с соот­ветс­тву­ющим «сло­ем», что, во‑пер­вых, упро­щает реали­зацию, а во‑вто­рых, уве­личи­вает быс­тро­дей­ствие.

В zRam, тех­нологии, поз­воля­ющей соз­давать сжа­тые RAM-дис­ки (что может быть край­не полез­ным для раз­мещения на них сво­па — пос­коль­ку память нам­ного быс­трее HDD, раз­ница в ско­рос­тях меж­ду реаль­ной памятью и сжа­той областью под­качки прак­тичес­ки неощу­тима, а при хорошем рас­кла­де стра­ницы памяти сжи­мают­ся в 2–3 раза) и став­шей ста­биль­ной, появи­лась воз­можность ука­зывать лимит памяти. Кро­ме того, была добав­лена под­дер­жка алго­рит­ма LZ4, обес­печива­юще­го в некото­рых слу­чаях боль­шую ско­рость и сте­пень сжа­тия, нежели исполь­зуемый до это­го LZO.

А в /proc/partitions появи­лось наконец отоб­ражение RAM-дис­ков.

 

Виртуализация

В дан­ной отрасли, пожалуй, самое зна­чимое изме­нение — под­дер­жка режима PVH в XEN. Дан­ный режим явля­ется ком­про­мис­сом меж­ду аппа­рат­ной и паравир­туали­заци­ей. Прос­лой­ка эму­лиру­емо­го железа отсутс­тву­ет как таковая, в то же вре­мя управле­ние памятью и при­виле­гиро­ван­ные инс­трук­ции выпол­няют­ся в самом ядре гос­тевой ОС. Раз­деление про­исхо­дит с помощью тех­нологий про­цес­сора. Изме­нения так­же кос­нулись и той час­ти сетевой под­систе­мы, которая отно­сит­ся к XEN, — теперь драй­веры вир­туаль­ных сетевых интерфей­сов под­держи­вают мно­жес­твен­ные оче­реди.

Кро­ме того, реали­зован проб­рос SCSI-устрой­ств в паравир­туаль­ное окру­жение, что поз­воля­ет совер­шать с дан­ными устрой­ства­ми спе­цифи­чес­кие опе­рации, которые недос­тупны при исполь­зовании API более высоко­го уров­ня, нап­ример перемот­ку лен­ты.

По­яви­лась воз­можность исполь­зовать EFI в слу­чае заг­рузки в качес­тве dom0. Пос­коль­ку те час­ти памяти и про­чие свя­зан­ные вещи, которые отно­сят­ся к EFI, находят­ся в рас­поряже­нии гипер­визора, ядро стан­дар­тным обра­зом дос­туп к ним получить не может. Соот­ветс­твен­но, исполь­зуют­ся вызовы гипер­визора — ког­да ядро в dom0 заг­ружа­ется и опре­деля­ет, что сис­тема у нас EFI-сов­мести­мая, с помощью дан­ных вызовов запол­няет­ся искусс­твен­ная струк­тура дан­ных EFI.

До­бав­лено устрой­ство KVM-VFIO, поз­воля­ющее гипер­визору KVM обра­щать­ся к драй­верам устрой­ств, которые написа­ны с исполь­зовани­ем фрей­мвор­ка VFIO и работа­ют, соот­ветс­твен­но, в User mode. KVM теперь так­же под­держи­вает вло­жен­ную вир­туали­зацию MPX — Memory Protection Extensions, тех­нологии, исполь­зуемой для защиты от атак на разыме­нова­ние ука­зате­ля, базиру­ющуюся на новых осо­бен­ностях про­цес­соров Intel.

 

Безопасность

Мно­го за про­шед­ший год появи­лось и усо­вер­шенс­тво­ваний в пла­не безопас­ности. Преж­де все­го отме­тим, что кон­тек­сты в SELinux теперь могут наз­начать­ся и для фай­лов в RAMFS. Так­же в полити­ке SELinux теперь мож­но вклю­чать опцию always_check_network, которая всег­да интер­пре­тиру­ет мет­ки SELinux для пакетов вклю­чен­ными, даже если не задано ни одно пра­вило Netfilter и не сто­ит ни одна фак­тичес­кая мет­ка.

Усо­вер­шенс­тво­ваны фун­кции, отно­сящи­еся к PRNG, в час­тнос­ти вмес­то taus88 в фун­кции prandom32() исполь­зует­ся алго­ритм taus113, который обес­печива­ет пери­од в 2113. Так­же вмес­то при­меши­вания (с помощью XOR) резуль­татов работы аппа­рат­ного генера­тора слу­чай­ных чисел к ито­гово­му буферу дан­ные резуль­таты добав­ляют­ся в пул энтро­пии на ран­них ста­диях.

До­бав­лена тех­нология KASLR — ран­домиза­ция адресно­го прос­транс­тва ядра. По идее, это обес­печива­ет защиту ядра про­тив атак на перепол­нение сте­ка, одна­ко на прак­тике, по иссле­дова­ниям некото­рых хакеров ядра, защита дос­таточ­но лег­ко обхо­дит­ся.

Яд­ро теперь под­держи­вает ком­пиляцию с новой опци­ей GCC4.9 — -fstack-protector-strong. Базовая идея всех подоб­ных методов зак­люча­ется в том, что­бы положить в стек некото­рую слу­чай­ную величи­ну сра­зу пос­ле того, как в нем ока­жет­ся ука­затель на воз­вра­щаемое зна­чение фун­кции. Перед воз­вра­том из фун­кции эта величи­на про­веря­ется, и, если она изме­нилась, код прек­раща­ет работу. Исполь­зование подоб­ных про­верок име­ет один побоч­ный эффект — они отни­мают немалое вре­мя. Для пары фун­кций это замет­но не будет, но вот в слу­чае с тысяча­ми и десят­ками тысяч фун­кций подоб­ное поведе­ние может край­не негатив­но ска­зать­ся на про­изво­дитель­нос­ти.

Та­ким обра­зом, перед раз­работ­чиками вста­ет воп­рос: какие имен­но фун­кции нуж­дают­ся в подоб­ной про­вер­ке? Один из наборов опций GCC как раз‑таки и опре­деля­ет какие. Опция -fstack-protector-all защища­ет все фун­кции, вне зависи­мос­ти от воз­вра­щаемо­го зна­чения. Эта опция самая парано­идаль­ная и самая мед­ленная. Опция же -fstack-protector дей­ству­ет толь­ко на те фун­кции, которые кла­дут в стек более чем вось­мибай­товый мас­сив char’ов. Пос­леднее, конеч­но, пок­рыва­ет боль­шинс­тво опас­ных мест. Боль­шинс­тво, но не все. Наконец, опция -fstack-protector-strong, в допол­нение к защите, добав­ляемой пре­дыду­щей опци­ей, защища­ет все локаль­ные мас­сивы незави­симо от их типа — даже в слу­чае, если они находят­ся в струк­турах или объ­еди­нени­ях, — и так­же защища­ет еще нес­коль­ко уяз­вимых мест. Дан­ный вари­ант защиты пок­рыва­ет при­мер­но 20% фун­кций ядра, что счи­тает­ся очень хорошим показа­телем — защита, добав­ляемая опци­ей -fstack-protector, пок­рывала все­го 2%. Так­же в ядро вклю­чена защита сте­ка и дан­ных модулей еще на самых ран­них ста­диях их заг­рузки — аж до раз­бора парамет­ров.

Ме­ханизм seccomp-bpf стал под­держи­вать JIT-ком­пиляцию BPF-филь­тров. Seccomp-bpf — механизм, поз­воля­ющий задавать огра­ниче­ния на сис­темные вызовы. Отли­чие от LSM зак­люча­ется в том, что боль­шинс­тво реали­заций пос­ледне­го защища­ет при­ложе­ния, навязы­вая им внеш­ние огра­ниче­ния. Seccomp-bpf же, хоть и поз­воля­ет пос­тупать ана­логич­но, боль­ше под­ходит для огра­ниче­ний, зашитых в код самого при­ложе­ния. При его написа­нии зада­ется спи­сок раз­решен­ных сис­темных вызовов и аргу­мен­тов для них и поведе­ние при некор­рек­тном сис­колле. Дан­ная фун­кци­ональ­ность поз­воля­ет весь­ма гиб­ко задавать пра­вила и при дол­жном при­мене­нии может силь­но зат­руднить жизнь ата­кующе­му. Иное дело, что огра­ниче­ния все же луч­ше соз­давать не тем же самым людям, что пишут при­ложе­ние, нуж­дающееся в защите.

Вне­сены изме­нения в SMACK — в час­тнос­ти, добав­лен «раз­решитель­ный» режим, пред­назна­чен­ный для отладки пра­вил. SMACK пред­став­ляет собой еще одну сис­тему при­нуди­тель­ного кон­тро­ля дос­тупа, отли­чающуюся от ана­логов прос­тотой. Все, что мож­но кон­фигури­ровать, кон­фигури­рует­ся через псев­дофай­ловую сис­тему. Обыч­ные тек­сто­вые пра­вила записы­вают­ся в опре­делен­ные фай­лы и объ­ектам прос­тавля­ются мет­ки. Под­держи­вают­ся огра­ниче­ния как для фай­лов, так и для сетевых под­клю­чений.

Бы­ла так­же реали­зова­на под­дер­жка NFC Secure Elements API, что, таким обра­зом, при наличии usermode-инс­тру­мен­тов обес­печит воз­можность совер­шения финан­совых тран­закций с исполь­зовани­ем дан­ного про­токо­ла.

 

Разное

В пла­ниров­щике про­цес­сов появи­лась новая полити­ка — SCHED_DEADLINE, которая обес­печива­ет алго­ритм пла­ниро­вания EDF (Earliest Deadline First). Дан­ный алго­ритм реали­зует идею выбора той задачи из оче­реди ожи­дающих про­цес­сов, которая наибо­лее близ­ка к дед­лай­ну. Это может понадо­бить­ся в сис­темах жес­тко­го реаль­ного вре­мени, ког­да про­цес­су нуж­но гаран­тирован­ное выпол­нение в любом слу­чае, нев­зирая на общее количес­тво про­цес­сов. Ранее, до сущес­тво­вания дан­ной полити­ки, пла­ниров­щик не мог гаран­тировать нуж­ное вре­мя выпол­нения задачи в некото­ром интерва­ле из‑за нак­ладных рас­ходов на перек­лючение, свя­зан­ных с общим количес­твом выпол­няющих­ся про­цес­сов.

Под­систе­ма uprobes (которую, в час­тнос­ти, исполь­зуют новей­шие вер­сии SystemTap) обза­велась под­дер­жкой извле­чения дан­ных из сте­ка и памяти про­цес­са; так­же теперь она под­держи­вает обра­бот­ку таких типов аргу­мен­тов, как битовые поля и сме­щения в фай­лах.

На сис­темах с UEFI появи­лась воз­можность заг­ружать 64-раз­рядное ядро нап­рямую из 32-раз­рядно­го EFI (да‑да, некото­рые EFI-про­шив­ки запус­кают­ся в 32-раз­рядном режиме), что ранее было невоз­можно из‑за проб­лем с вызовом EFI-фун­кций.

До­бав­лен Power Capping Framework, пре­дос­тавля­ющий дос­туп через sysfs к уни­фици­рован­ному интерфей­су управле­ния огра­ниче­ниями питания. В нем под­держи­вают­ся так называ­емые зоны питания, пред­став­ляющие раз­личные час­ти сис­темы, которые могут управлять­ся и монито­рить­ся с помощью методов огра­ниче­ния питания. Каж­дая «зона питания» содер­жит набор атри­бутов и механиз­мов управле­ния, которые вли­яют на огра­ниче­ния питания. «Зоны питания» могут быть орга­низо­ваны иерар­хичес­ки в соот­ветс­твии с реаль­ным положе­нием дел в дан­ной сис­теме (нап­ример, диск — дис­ковая под­систе­ма — материн­ская пла­та), что поз­воля­ет при­менять огра­ниче­ния питания к набору устрой­ств, а если необ­ходима более точ­ная нас­трой­ка, то и к нуж­ному устрой­ству.

Ус­корено возоб­новле­ние работы пос­ле «засыпа­ния» за счет ино­го алго­рит­ма работы с жес­тким дис­ком — ранее драй­вер ATA-пор­та бло­киро­вал всю работу, пока жес­ткий диск не «прос­нется», что, таким обра­зом, бло­киро­вало работу ядра. Сей­час же все коман­ды, посыла­емые драй­веру, по заветам небезыз­вес­тно­го Шарико­ва ста­новят­ся в оче­редь и выпол­няют­ся асин­хрон­но.

От sysfs отпочко­валась kernfs — теперь sysfs явля­ется под­мно­жес­твом пос­ледней. Так­же пла­ниру­ется на ее осно­ве соз­давать новые псев­дофай­ловые сис­темы — такие как cgroupfs.

По­яви­лась уни­фици­рован­ная иерар­хия cgroup. Рань­ше мог­ло соз­давать­ся мно­жес­тво иерар­хий (одна для CPU, дру­гая для blkio и так далее) и про­цесс мог находить­ся одновре­мен­но в нес­коль­ких. Это уве­личи­вало гиб­кость, но при­води­ло к излишним зат­ратам ресур­сов и соз­давало труд­ности при вза­имо­дей­ствии обра­бот­чиков раз­личных иерар­хий.

На­чата работа над сбор­кой ядра с помощью clang. Проб­лема зак­люча­ется в том, что оно исполь­зует мно­жес­тво GCC-спе­цифич­ных осо­бен­ностей, в час­тнос­ти мас­сивы перемен­ной дли­ны, которые, впро­чем, уже замене­ны на экви­валент, соз­данный с помощью мак­роса SHASH_DESC_ON_STACK() и сов­мести­мый со стан­дартом C99.

До­бав­лена под­дер­жка пятой вер­сии GCC.

Бы­ло реали­зова­но нес­коль­ко новых сис­темных вызовов:

  • getrandom(), пре­дос­тавля­ющий аль­тер­натив­ный метод генера­ции слу­чай­ных чисел. Это может понадо­бить­ся в тех ситу­ациях, ког­да исчерпа­ны все фай­ловые дес­крип­торы и открыть фай­лы устрой­ств не получа­ется. Рань­ше некото­рые биб­лиоте­ки в этой ситу­ации перек­лючались на менее безопас­ный алго­ритм генера­ции;
  • renameat2(), поз­воля­ющий пере­име­новать фай­лы один в дру­гой. Это поз­воля­ет, нап­ример, про­извести ато­мар­ную опе­рацию пере­име­нова­ния сим­линков в дереве катало­гов;
  • bpf(), реали­зующий дос­туп к фун­кци­ям eBPF — рас­ширен­ного BPF, о котором писалось выше. Этот сис­темный вызов край­не мно­гог­ранен и объ­еди­няет мно­жес­тво опе­раций, которые допус­тимо про­изво­дить с исполь­зовани­ем новой под­систе­мы; для упро­щения работы исполь­зуют­ся фун­кции‑обер­тки. Конеч­но, этот сис­темный вызов дос­таточ­но опа­сен: заг­рузка в ядро неп­роверен­ного кода может пов­лечь за собой фаталь­ные пос­ледс­твия. Имен­но поэто­му боль­шую часть кода дан­ного пат­чсе­та занима­ет верифи­катор, который сле­дит за внут­ренни­ми регис­тра­ми и в том чис­ле пре­дот­вра­щает чте­ние неини­циали­зиро­ван­ных регис­тров. Сам же сис­темный вызов тре­бует капаби­лити CAP_SYS_ADMIN и зап­реща­ет выпол­нение кода, выпущен­ного не под GPL-лицен­зией;
  • kexec_file_load(), пре­дот­вра­щающий заг­рузку непод­писан­ных ядер, что необ­ходимо для сов­мести­мос­ти с UEFI Secure Boot;
  • seccomp(), добав­ляющий (вмес­те с допол­нитель­ным пат­чсе­том) воз­можность филь­тро­вать сис­темные вызовы не толь­ко у про­цес­сов, но так­же и у потоков — ранее это было невоз­можно.

Усо­вер­шенс­тво­ван алго­ритм опре­деле­ния раз­мера рабоче­го набора, что необ­ходимо для ука­зания того, какие дан­ные помещать в своп.

На­конец, пред­при­няты шаги для решения проб­лемы 2038 года, свя­зан­ной с перепол­нени­ем 32-бит­ного типа дан­ных time_t — счет­чика секунд от начала UNIX-эпо­хи.

kdbus

В ядре, воз­можно, ско­ро появит­ся новый механизм IPC — kdbus. Он осно­ван на тех же прин­ципах, что и D-Bus, но име­ет сле­дующие пре­иму­щес­тва:

  • бо­лее высокая про­изво­дитель­ность за счет мень­шего перек­лючения кон­тек­стов;
  • по­вышен­ная безопас­ность из‑за отсутс­твия вли­яния user-mode-про­цес­сов на содер­жимое сис­темной шины и воз­можнос­ти исполь­зовать LSM для задания политик огра­ниче­ния дос­тупа;
  • воз­можность исполь­зования дан­ного механиз­ма на ран­них эта­пах заг­рузки.
 

Заключение

В ядро Linux добав­ляют­ся все новые и новые воз­можнос­ти. С одной сто­роны, это сви­детель­ству­ет о том, что над ним плот­но работа­ют. С дру­гой же... объ­ем кода ядра уже сей­час пуга­юще огро­мен. Да, боль­шую часть фун­кций мож­но отклю­чить при сбор­ке, да, ядро модуль­ное, но, помилуй­те, зачем в ядре интер­пре­татор байт‑кода или сбор­щик мусора в блоч­ной под­систе­ме? Код, работа­ющий в при­виле­гиро­ван­ном режиме (который, напом­ню, в сов­ремен­ных сис­темах име­ет дос­туп прак­тичес­ки ко все­му железу и памяти), в иде­але дол­жен выпол­нять исклю­читель­но задачи пла­ниро­вания про­цес­сорно­го вре­мени и рас­пре­деле­ния памяти. Код ядра Linux, хоть и работа­ет в при­виле­гиро­ван­ном режиме, этим усло­виям даже с боль­шой натяж­кой не удов­летво­ряет.

Воз­ника­ет законо­мер­ный воп­рос: к чему все это при­ведет? Пока что вид­но лишь три пути:

  1. Раз­работ­чики упрутся в какую‑либо фун­дамен­таль­ную проб­лему, свя­зан­ную с архи­тек­турой ядра.
  2. Раз­работ­чики возь­мут­ся за ум и перепи­шут ядро целиком с уче­том вышес­казан­ного.
  3. Вмес­то аппа­рат­ного раз­деления про­цес­сов будет исполь­зовать­ся прог­рам­мное. На ум сра­зу при­ходят Singularity от Microsoft Research и JNode — ОС на Java.

Тре­тий вари­ант пока что выг­лядит наибо­лее реаль­ным, даже нес­мотря на кучу проб­лем, которые его реали­зация может потянуть за собой. Пос­мотрим, что будет даль­ше.

Оставить мнение